【发布时间】:2011-06-03 17:49:02
【问题描述】:
我在使用 posix 信号量进行同步时遇到问题。这是我写的代码
sem_t *sem1, *sem2;
void* test1() {
int rv;
while(1) {
rv = sem_wait(sem1);
printf("sem_wait(&sem1) = %d\n",rv);
printf("test1\n");
rv = sem_post(sem2);
printf("sem_post(&sem2) = %d\n\n",rv);
}
return NULL;
}
void* test2() {
while(1) {
rv = sem_wait(sem2);
printf("sem_wait(&sem2) = %d\n",rv);
printf("test2\n");
rv = sem_post(sem1);
printf("sem_post(&sem1) = %d\n\n",rv);
}
return NULL;
}
int main (int argc, const char * argv[]) {
pthread_t t1,t2;
sem1 = sem_open("sem1", O_CREAT | O_EXCL, 0644, 1);
if (sem1 == SEM_FAILED){
perror("sem1_init");
sem_close(sem1);
return;
}
sem2 = sem_open("sem2", O_CREAT | O_EXCL, 0644, 0);
if (sem2 == SEM_FAILED){
perror("sem2_init");
sem_close(sem1);
sem_close(sem2);
return;
}
pthread_create(&t1, NULL, &test1, NULL);
pthread_create(&t2, NULL, &test2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}
我的预期是,由于我将sem1 初始化为 1,sem2 初始化为 0,test1 将是第一个运行的函数,然后它们将交替运行直到时间结束。
相反,它不起作用,我的意思是在日志中我读了很多次“test1”,很多次“test2”,有一段时间交替出现,然后又没有任何顺序。
有人可以告诉我我的错误在哪里吗?
ps。不知道它是否有用,但我正在运行 MacOSX 10.6.7
编辑:
我更新了我的代码,删除了对sem_init 和sem_getvalue 的所有调用(在MacOS 下都不存在),使用sem_open 来初始化信号量,它似乎可以工作。
然而,我发现了一个奇怪的问题,可能是因为我对sem_open 调用的误解:每次我重新启动程序时,如果我为信号量重用相同的名称,我都会收到错误File exists。如何强制重用相同的标识符?
除了。根据手册页,sem_wait 如果成功则返回 0,否则返回 -1。如果我收到 1 意味着什么(这总是发生在 test2 中)?
【问题讨论】:
-
首先,编译启用警告的程序。此外,检查所有调用的返回值是否存在错误。然后,看看这个 stackoverflow.com/questions/1413785/sem-init-on-os-x 和 stackoverflow.com/questions/4136181/… 是不是你的问题。
-
@nos 哇,如果我可以给苹果一个-1,因为我没有实现这个,我会的。 :P(当然,我同意:总是检查错误......)
-
asveikau 是对的,MacOS 下似乎没有
sem_init和sem_getvalue......我预计至少会有一个警告,相反我什至收到代码完成......无论如何,我编辑了原始帖子并进行了一些更正。不确定这是一个真正解决问题的方法,但它似乎有效。检查你们中的一些人是否知道我在帖子末尾添加的问题的答案 -
@Summit Guy:如果他删除了
O_EXCL,那么它将打开具有不确定起始值的现有信号量对象。 -
@Saphrosit:您更新的代码对我来说很好(第一次运行)。程序终止后,命名信号量会在内核中持续存在。您需要致电
sem_unlink以完全删除信号量。如果您的程序仅由诸如 Ctrl-C (SIGINT) 之类的信号终止,那么您需要使用signal(2)或sigaction(2)设置一个信号处理程序,该处理程序将在退出前调用sem_unlink。
标签: c synchronization posix semaphore