我有一个用c语言编写程序的任务,它将打印到shell的数字1 - 100.我必须使用5个进程。第一个将打印1,6,11,16 ......第二个,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);
}
答案 0 :(得分:0)
你的程序结构基本上是正确的。
所以,我可以打电话,而不是那些
wait
sem_wait
?我应该作为一个论点传递什么?我需要吗? 创建sem_t sem
并致电sem_init(&sem, 0, 0)
?
不,你和ThCP混淆了System V和POSIX信号量。由于您使用的是System V信号量(确实更适合您的任务),因此等待的函数为semop
。
打印后我需要使用信号来增加另一个 信号量值为1。
通过 signal ,当然不是函数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();
}
不要忘记删除功能exit(1)
中的increaseallbutI()
来电!