0

プロセスを使用して競合状態プログラムを作成する必要がありました。私もそうしました。現在、セマフォを使用してそれを解決しようとしています。2つのクリティカルセクションがあり、を使用して作成したセマフォを使用してそれらを保護しようとしていinitStem()ますsemctl()P()2番目のパラメーターで指定されたセマフォのミューテックスをV()インクリメントおよびデクリメントします。

残念ながら、私の競合状態はまだ残っているようです:私の出力は:

value in parent: 4
value after child exec: 4

いつあるべきか:

value in parent: 4
value after child exec: 5

(5 + 1-1 = 5 ..。)

これが私のコードです:

#define KEY 4567
#define PERMS 0660
#define ID_PROJ "race"
#define NB_SEMAPHORES 1

int initSem(char **argv);
int P(int semid, int semnum);
int V(int semid, int semnum);

int main(int argc, char **argv) {

    int id, pid1;
    int *shared;
    int tmp;

if ((id = shmget(KEY, 2*sizeof(int), IPC_CREAT | PERMS)) == -1) {
    perror("shmget");
    exit(-1);
}

shared=(int *)shmat(id, NULL, 0);
shared[0]=5; // value
shared[1]=initSem(argv); // semaphore id

if ((pid1=fork()) == 0) {
    P(shared[1], 0); // Start critical section
    tmp=shared[0];
    tmp++;
    sleep(2);
    shared[0]=tmp;
    V(shared[1], 0); // End critical section
    exit(0);
}
else {
    P(shared[1], 0); // Start
    tmp=shared[0];
    tmp--;
    sleep(4);
    shared[0]=tmp;
    V(shared[1], 0); // End

    printf("value in parent: %d\n", shared[0]);

    waitpid(pid1, NULL, 0);
    printf("value after child exec: %d\n", shared[0]);
    shmctl(id, IPC_RMID, NULL);
}
}

だから私は疑問に思っています:私は自分のセマフォを正しく使用していますか?両方のプロセスで同じセマフォを使用して正しく実行していますか?

編集 :

セマフォと対話するために使用している3つの関数は次のとおりです。

int initSem(char **argv) {
    int i,semid;
    key_t key=ftok(argv[0], 'P');
    semid=semget(key, NB_SEMAPHORES, IPC_CREAT | PERMS);
    for(i=0 ; i<NB_SEMAPHORES ; i++)
            semctl(key, i, SETVAL, 1);
    return semid;
}

int P(int semid, int semnum) {
    struct sembuf op;
    op.sem_num=semnum;
    op.sem_op=-1;
    op.sem_flg=0;
    semop(semid, &op, 1);
}

int V(int semid, int semnum) {
    struct sembuf op;
    op.sem_num=semnum;
    op.sem_op=1;
    op.sem_flg=0;
    semop(semid, &op, 1);
}
4

2 に答える 2

0

ゼロ以外に設定してを使用sem_init()してセマフォを作成してくださいpshared

于 2013-02-20T17:55:37.897 に答える
0

さて、問題はinitSem私が使用した場所にありました

semctl(key, i, SETVAL, 1);

それ以外の

semctl(semid, i, SETVAL, 1);

そうでなければ私のコードは正しいです。

于 2013-02-25T22:01:11.400 に答える