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