我正在尝试创建一个程序,该程序会分析睡眠几秒钟的子进程,然后释放正在等待的父进程的信号量。我花了几天时间阅读信号量和在线研究,但这一切都让人非常困惑。此外,每个示例都是大量代码,看起来很简单,每个代码都完全不同。
编辑:DERP!所以,代码不起作用。孩子的分叉很好,但是父母永远被困在sem_wait上。因此,我实现信号量的方式似乎有问题。这是我到目前为止所拥有的:
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int j, dummy, intCast;
sem_t s;
if (argc < 2 || strcmp(argv[1], "--help") == 0){
printf("Usage: sem_sync X (X is one or more ints)");
exit(EXIT_FAILURE);
}
setbuf(stdout, NULL); /* Make stdout unbuffered, since we
terminate child with _exit() */
printf(" Parent started\n");
sem_init(&s, 0, 0);
for (j = 1; j < argc; j++) {
switch (fork()) {
case -1:
printf("Error on fork %d", j);
exit(EXIT_FAILURE);
case 0: /* Child */
intCast = atoi(argv[j]); // Casts the argument into an integer
printf("Child sleeping for %d seconds\n",intCast);
sleep(intCast);
sem_post(&s);
_exit(EXIT_SUCCESS);
default: /* Parent loops to create next child */
break;
}
}
printf(" Parent is waiting\n");
sem_wait(&s);
printf(" Parent ready to go\n");
exit(EXIT_SUCCESS);
}
这是使用sem_open()和sem_close()
的工作代码int main(int argc, char *argv[])
{
int j, intCast;
sem_t *s;
printf(" Parent started\n");
s = sem_open("file1", O_CREAT, 0600, 0);
if (s == SEM_FAILED){
printf("sem_open() failed. errno:\n");
}
for (j = 1; j < argc; j++) {
switch (fork()) {
case -1:
printf("Error on fork %d", j);
exit(EXIT_FAILURE);
case 0: /* Child */
intCast = atoi(argv[j]);
printf("Child sleeping for %d seconds\n",intCast);
sleep(intCast);
sem_post(s);
_exit(EXIT_SUCCESS);
default:
break;
}
}
printf(" Parent is waiting\n");
for (j = 1; j < argc; j++){
sem_wait(s);
}
sem_close(s);
exit(EXIT_SUCCESS);
}
答案 0 :(得分:1)
使用sem_open()
代替sem_init()
。使用sem_init()
创建的信号量不会在进程间共享,除非您在共享内存中创建它们。将sem_open()
用于您想要做的事情要容易得多。
修改:请记住,sem_open()
会创建一个您需要使用sem_unlink()
删除的持久信号量。如果前一次调用可能存在杂散文件,您可能希望在打开文件之前取消链接,如下所示:
sem_unlink(filename);
sem_open(filename, O_CREAT, etc...);
以便在打开之前删除命名的信号量。否则,如果它已经存在,sem_open
将打开现有的信号量并继承信号量中已有的任何计数。