子进程中的命名信号量让我感到困惑
Named Semaphores in child processes confusing me
我有这个非常简单的程序来测试命名信号量:
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/shm.h>
#include <fcntl.h>
sem_t thing;
void processOne() {
sleep(1);
int l;
sem_getvalue(&thing, &l);
printf("processOneThing: %d\n", l);
}
void processTwo(){
sem_wait(&thing);
printf("done");
}
int main(int argc, char **argv) {
int pidOne, pidTwo;
thing = *sem_open("/testest", O_CREAT|O_EXCL,0777,1);
pidTwo=fork();
if(pidTwo==0){
processTwo();
}
else{
pidOne=fork()
if(pidOne==0){
processOne();
}
else{
}
wait(&pidTwo);
wait(&pidOne);
}
sem_unlink("/testest");
sem_close(&thing);
}
输出为:
doneprocessOneThing: 1
这意味着第二个进程递减了信号量,但是它在第一个子进程中的值仍然是 1...
我不知道我做错了什么,我查看了命名信号量文档,但找不到太多可以帮助我解决这个问题的信息。
我正在编译使用:
gcc test.c -pthread
我们将不胜感激。
首先,代码缺少;在此行的末尾:
else{
pidOne=fork() <------ here
if(pidOne==0){
processOne();
}
它无法为 wait() 原型#include。但是纠正这些问题我得到了和你一样的输出。那么发生了什么?问题在于您如何创建信号量:
sem_t thing;
...
thing = *sem_open("/testest", O_CREAT|O_EXCL,0777,1);
来自sem_open的return是创建的信号量的地址。但是您正在取消对该地址的引用并将内容的副本放入您的变量中。这意味着 thing 实际上不是您创建的信号量,而只是保存状态信息的结构的副本。结果是与代码中的事物交互实际上并不是与您想要的交互。 (事实上 ,如果您检查 sem_wait() 和 sem_getvalue() 上的 return 值,您可能会得到一些不正确的指示。)
如果您将 thing 设为指向信号量的指针并与之交互,您将得到以下输出:
done
processOneThing: 0
这是我认为你期望看到的。您可以在此处尝试更正后的代码:
我有这个非常简单的程序来测试命名信号量:
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/shm.h>
#include <fcntl.h>
sem_t thing;
void processOne() {
sleep(1);
int l;
sem_getvalue(&thing, &l);
printf("processOneThing: %d\n", l);
}
void processTwo(){
sem_wait(&thing);
printf("done");
}
int main(int argc, char **argv) {
int pidOne, pidTwo;
thing = *sem_open("/testest", O_CREAT|O_EXCL,0777,1);
pidTwo=fork();
if(pidTwo==0){
processTwo();
}
else{
pidOne=fork()
if(pidOne==0){
processOne();
}
else{
}
wait(&pidTwo);
wait(&pidOne);
}
sem_unlink("/testest");
sem_close(&thing);
}
输出为:
doneprocessOneThing: 1
这意味着第二个进程递减了信号量,但是它在第一个子进程中的值仍然是 1...
我不知道我做错了什么,我查看了命名信号量文档,但找不到太多可以帮助我解决这个问题的信息。
我正在编译使用:
gcc test.c -pthread
我们将不胜感激。
首先,代码缺少;在此行的末尾:
else{
pidOne=fork() <------ here
if(pidOne==0){
processOne();
}
它无法为 wait() 原型#include
sem_t thing;
...
thing = *sem_open("/testest", O_CREAT|O_EXCL,0777,1);
来自sem_open的return是创建的信号量的地址。但是您正在取消对该地址的引用并将内容的副本放入您的变量中。这意味着 thing 实际上不是您创建的信号量,而只是保存状态信息的结构的副本。结果是与代码中的事物交互实际上并不是与您想要的交互。 (事实上 ,如果您检查 sem_wait() 和 sem_getvalue() 上的 return 值,您可能会得到一些不正确的指示。)
如果您将 thing 设为指向信号量的指针并与之交互,您将得到以下输出:
done
processOneThing: 0
这是我认为你期望看到的。您可以在此处尝试更正后的代码: