【发布时间】:2020-03-20 06:37:57
【问题描述】:
我正在处理一项家庭作业,其中涉及实施信号量以强制子进程之间的互斥。我的大部分代码都在工作,除了我没有正确使用信号量。我发现的文章没有多大帮助。有人可以向我解释一下 POSIX 信号量是如何工作的吗?
例如,如果我有一个父进程使用fork() 和execl() 派生子进程:
sem=sem_open("/semaphore1",O_CREAT|O_EXCL,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,1);
for (i = 0; i < 3; i++)
{
//three child process are spawned in the image of the parent
child[i] = fork();
//establish whether all children were created successfully
switch (child[i])
{
//child process creation failed...
case -1:
rpterror ((char *)"fork failure", pname);
exit(1);
//given that the fork() was successful (the children were spawned successfully)...
case 0:
sprintf (pname, "shmc%d", i+1);
execl("shmc1", pname, ascshmid, (char *)0);
perror ("execl failed");
exit (2);
}
}
并且孩子想要访问和修改共享内存段(由父创建)中的值:
sem=sem_open("/semaphore1", O_RDWR);
while ( !all_out)
{ /* loop to sell all seats */
/* puts the process to sleep for an amount of time, then decreases the amount of seats available. Before printing out the new count of seats, the process sleeps again. Finally, it prints the seat count until there are no more seats left.*/
if (class_ptr->seats_left > 0)
{
sem_wait(sem);
sleep ( (unsigned)rand()%5 + 1);
class_ptr->seats_left--;
sleep ( (unsigned)rand()%5 + 1);
cout << pname << " SOLD SEAT -- " << class_ptr->seats_left << " left" <<endl;
sem_post(sem);
}
else
{
all_out++;
cout << pname << " sees no seats left" << endl;
}
sleep ( (unsigned)rand()%10 + 1);
}
其中seats_left 是共享变量。
运行此代码会给我一个如下所示的输出。共享变量的初始值为 15:
shmc1 SOLD SEAT -- 14 left
shmc2 SOLD SEAT -- 13 left
shmc3 SOLD SEAT -- 12 left
shmc1 SOLD SEAT -- 11 left
shmc2 SOLD SEAT -- 10 left
shmc3 SOLD SEAT -- 9 left
shmc1 SOLD SEAT -- 8 left
shmc2 SOLD SEAT -- 7 left
shmc3 SOLD SEAT -- 6 left
shmc2 SOLD SEAT -- 5 left
shmc1 SOLD SEAT -- 4 left
shmc3 SOLD SEAT -- 3 left
shmc2 SOLD SEAT -- 2 left
shmc1 SOLD SEAT -- 1 left
shmc1 sees no seats left
shmc3 SOLD SEAT -- 0 left
shmc3 sees no seats left
shmc2 SOLD SEAT -- -1 left
shmc2 sees no seats left
Parent removing shm
如您所见,最后是我的进程在另一个进程进入临界区的同时进入临界区的地方。有谁知道这是为什么?
【问题讨论】: