C 使用5个信号量和进程打印数字1到100

C 使用5个信号量和进程打印数字1到100,c,linux,semaphore,C,Linux,Semaphore,我的任务是用c语言编写一个程序,将数字1-100打印到shell中。我必须使用5个进程。第一个将打印1,6,11,16。。。第二个2,7,12,17。。。等等 我需要创建5个信号量来同步这些进程。 这五个信号量需要初始化为0、1、2、3、4 这是否意味着我需要使用semctl 另外,据说打印1的过程必须用4初始化,打印2的过程必须用3初始化,依此类推 如何执行此操作 最后,据说在打印一个数字之前,我需要执行等待4次以将信号量值减少4,在打印该数字之后,我需要使用信号将其他信号量值增加1 我尝试了

我的任务是用c语言编写一个程序,将数字1-100打印到shell中。我必须使用5个进程。第一个将打印1,6,11,16。。。第二个2,7,12,17。。。等等 我需要创建5个信号量来同步这些进程。 这五个信号量需要初始化为0、1、2、3、4

这是否意味着我需要使用
semctl

另外,据说打印1的过程必须用4初始化,打印2的过程必须用3初始化,依此类推

如何执行此操作

最后,据说在打印一个数字之前,我需要执行等待4次以将信号量值减少4,在打印该数字之后,我需要使用信号将其他信号量值增加1

我尝试了很多方法,但都解决不了。我不了解这些进程之间的时间安排——如何让每个进程使用特定的信号量?我以后如何“返回”到那个流程,而不在我已经拥有的子流程中创建子流程

这是我能达到的最大目标:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void increaseallbutI(int i);
void cleanup();
int semid;
struct sembuf sops[1];

union semun
{
    int val;
    struct semid_ds * buff;
    unsigned short *array;
    struct seminfo *_buf;
};
union semun semarg;

void main()
{
    int i, j, k, status, num = 1;
    pid_t pid[5];

    semid=semget(IPC_PRIVATE, 5, 0600);

    for(i = 1; i < 17; i++)
    {
        signal(i, &cleanup);
    }

    for(i = 0; i < 5; i++)
    {
        semarg.val = 4 - i;
        semctl(semid, i, SETVAL, semarg);
    }

    sops->sem_num = 0;
    sops->sem_flg = 0;

    for(i = 0; i < 5; i++)
    {
        if(fork()==0)
        {
            for(j = i + 1; j < 101; j += 5)
            {
                wait(&status);
                wait(&status);
                wait(&status);
                wait(&status);
                printf("%d\n", j);
                fflush(stdout);

                signal(i, &increaseallbutI);
            }
        }
    }
}

void cleanup()
{
    semctl ( semid , 0 , IPC_RMID , semarg );
    exit(1);
}

void increaseallbutI(int i)
{
    int k;
    for(k = 0; k < 5; k++)
    {
        if(k != i)
        {
            sops->sem_op = 1;
            sops->sem_num = k;
            semop ( semid , sops , 1 );
        }
    }
    exit(1);
}
#包括
#包括
#包括
#包括
#包括
#包括
无效增量allbuti(int i);
空洞清理();
int-semid;
结构sembuf标准操作程序[1];
联合塞蒙
{
int-val;
结构半圆形*浅黄色;
无符号短*数组;
结构seminfo*_buf;
};
塞蒙-塞马尔格联盟;
void main()
{
int i,j,k,status,num=1;
pid_t pid[5];
semid=semget(IPC_PRIVATE,50600);
对于(i=1;i<17;i++)
{
信号(i、i和c);
}
对于(i=0;i<5;i++)
{
semarg.val=4-i;
semctl(semid,i,SETVAL,semarg);
}
SOP->sem_num=0;
SOP->sem\U flg=0;
对于(i=0;i<5;i++)
{
如果(fork()==0)
{
对于(j=i+1;j<101;j+=5)
{
等待(&状态);
等待(&状态);
等待(&状态);
等待(&状态);
printf(“%d\n”,j);
fflush(stdout);
信号(i和递增所有但i);
}
}
}
}
空洞清理()
{
semctl(semid,0,IPC_RMID,semarg);
出口(1);
}
无效增量allbuti(整数i)
{
int k;
对于(k=0;k<5;k++)
{
如果(k!=i)
{
SOP->sem_op=1;
SOP->sem_num=k;
semop(semid,标准作业程序,1);
}
}
出口(1);
}

您的程序结构基本正确


因此,我可以调用
sem_wait
?我应该把什么作为论点?我需要吗 创建一个
sem\u t sem
并调用
sem\u init(&sem,0,0)

不,您和ThCP混淆了SystemV和POSIX信号量。因为您使用的是SystemV信号量(确实更适合您的任务),所以用于等待的函数是

打印完号码后,我需要使用信号来增加其他号码 信号量值乘以1

通过信号,当然不是函数
signal
的意思,而是在函数
increaseallbutI()
中正确执行的信号量值的增加被称为信号

因此,主循环和程序的结尾可能是:

    …
    for (i = 0; i < 5; i++)
    {
        if (fork() == 0)
        {
            struct sembuf sop = { i, -4, };
            for (j = i + 1; j < 101; j += 5)
            {
                semop(semid, &sop, 1);
                printf("%d\n", j);
                increaseallbutI(i);
            }
            exit(0);    // child is done
        }
    }
    do ; while (wait(&status) > 0); // wait till all children are finished
    cleanup();
}
…
对于(i=0;i<5;i++)
{
如果(fork()==0)
{
结构sembuf sop={i,-4,};
对于(j=i+1;j<101;j+=5)
{
semop(semid和sop,1);
printf(“%d\n”,j);
增加所有Buti(i);
}
退出(0);//子项已完成
}
}
做while(等待(&status)>0);//等到所有的孩子都做完
清理();
}

不要忘记删除
退出(1)
调用函数
increaseallbutI()

您的程序无法正常工作,因为您正在使用wait()函数,其行为是在子进程返回之前停止父进程。这意味着每个进程(父进程和子进程)将等待永远不会到达的退出。实际上,您想要使用的是一个sem_wait函数,它将信号量计数减少1,因此需要4个。类似地,您需要某种类型的sem_信号来增加信号量的值。他们是否告诉您实现自己的信号量,或者允许您使用库?首先,非常感谢您的回答。第二,我认为我可以使用库。因此,我可以调用
sem\u wait
,而不是那些
wait
s?我应该把什么作为论点?我是否需要创建一个
sem\t sem
并调用
sem\u init(&sem,0,0)
?您必须使用sem\u wait。如果您使用的是posix信号量,那么您应该在文档中检查正确的语法,然后应该初始化5个不同的信号量并正确初始化它们(这意味着使用sem_init和信号量的正确值,例如,对于sem 1,使用4等等)。