0

私はC Linux、引数によって入力された 2 つのスポットと "n" 個のプロセスを持つ 1 つのセマフォがある演習をコーディングしようとしています。最初の 2 つのプロセスが 2 つのスポットをそれぞれ 5 秒間使用してセマフォを使用し、残りのプロセスが処理を行うためにセマフォを離れる必要があります。問題は、他のすべてのプロセスがセマフォが解放されるのを待つわけではなく、一部のプロセスでセマフォ エラーが表示されることです (下部の結果を参照)。waitipid関数と関数があるため、問題は子プロセスの待機にあると思いますがwait、セマフォに空きスポットがある場合は、実行中の子プロセスがそれを使用できる必要があります。コードは次のとおりです。

//gcc SemaphoreExample.c -o s
//./s 5

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>

void semaphoreTask(int semid, int semnum, int semBusy)
{
    struct sembuf data;
    data.sem_num = semnum;
    data.sem_flg = 0;
    data.sem_op = semBusy;

    if(semop(semid,&data,1) == -1)
    {
        printf("\nSemaphore Error\n");
        exit(-1);
    }
}

int main(int argc, char *argv[])
{
    int i, fdSemaphore, quantity, fdsemctl, j;
    pid_t pid[15];

    system("clear");

    if(argc-1 < 1)
    {
        printf("Some arguments are missing\n");
        return EXIT_FAILURE;
    }

    printf("Number of arguments entered:\n\nargc: %d\n\nValues from the arguments:\n\n",argc-1);

    for(i=0;i<argc;i++)
    {
        printf("argv[%d]: %s\n",i,argv[i]);
    }

    printf("\n\n");

    fdSemaphore = semget(1234,1,IPC_CREAT|0777);

    if(fdSemaphore == -1)
    {
        printf("\nError creating the Semaphore\n");
        return EXIT_FAILURE;
    }

    fdsemctl = semctl(fdSemaphore,0,SETVAL,2);

    if(fdsemctl == -1)
    {
        printf("\nError opening the Semaphore\n");
        return EXIT_FAILURE;
    }

    quantity = atoi(argv[1]);

    for(i=0;i<quantity;i++)
    {
        pid[i] = fork();

        if(pid[i] == -1)
        {
            printf("\nError creating the Child Process\n");
            return EXIT_FAILURE;
        }

        if(pid[i] == 0)
        {
            semaphoreTask(fdSemaphore,0,-1);
            printf("\n[%d] I go to sleep\n",getpid());
            sleep(5);
            printf("\n[%d] I wake up\n",getpid());
            semaphoreTask(fdSemaphore,0,1);
        }
        else
        {
            //printf("\nJust wait\n");
            waitpid(pid[i],NULL,WNOHANG);
        }
    }

    for(j=0;j<quantity;j++)
    {
        wait(NULL);
    }

    semctl(fdSemaphore,0,IPC_RMID);

    return EXIT_SUCCESS;
}

これは私が得た結果です:

Result:

Number of arguments entered:

argc: 1

Values from the arguments:

argv[0]: ./s
argv[1]: 5


[2845] I go to sleep

[2844] I go to sleep

[2845] I wake up

[2844] I wake up

Semaphore Error

[2843] I go to sleep

Semaphore Error

Semaphore Error

[2843] I wake up

Semaphore Error

wait使用するか、またはwaitpidのみ使用する必要がありますか?

4

2 に答える 2

1

問題は、分岐した子によってセマフォが削除されていることです。

行後

semaphoreTask(fdSemaphore,0,1);

追加

exit(0);
于 2013-10-05T06:56:20.123 に答える
0

sem_post および sem_wait 呼び出しを使用すると、必要なものを実装するのがはるかに簡単になります。私は OpenBSD システムを使用していますが、Linux にも同じ機能があると想定しています。

于 2013-10-04T23:53:54.573 に答える