【发布时间】:2015-06-20 01:10:20
【问题描述】:
我在 C 中练习并发,我似乎遇到了一些信号量问题。 我在 MacOSX 中使用 Xcode 6.3.2。
这是一个看起来很奇怪的示例程序:该示例的目的是打印 ABCD 或 BACD 字符串
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <errno.h>
void *thread1(void*);
void *thread2(void*);
sem_t *sem0, *sem1, *sem2;;
int main(int argc, const char * argv[]) {
pthread_t t1, t2;
sem0 = sem_open("sem0", O_CREAT, 0600, 2);
sem1 = sem_open("sem1", O_CREAT, 0600, 0);
sem2 = sem_open("sem2", O_CREAT, 0600, 0);
// quick check
if (sem0 == SEM_FAILED || sem1 == SEM_FAILED || sem2 == SEM_FAILED) {
printf("Something went wrong\n");
return 0;
}
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_close(sem0);
sem_close(sem1);
sem_close(sem2);
return 0;
}
void *thread1(void* arg) {
int n=0;
while (n<10) {
sem_wait(sem0);
printf("A");
fflush(stdout);
sem_wait(sem1);
printf("C");
fflush(stdout);
sem_post(sem2);
n++;
}
pthread_exit(NULL);
}
void *thread2(void* arg) {
int n=0;
while (n<10) {
sem_wait(sem0);
printf("B");
fflush(stdout);
sem_post(sem1);
sem_wait(sem2);
printf("D\n");
fflush(stdout);
sem_post(sem0);
sem_post(sem0);
n++;
}
pthread_exit(NULL);
}
如果我正确实现了信号量,结果将是 ABCD 或 BACD,但实际上我会得到各种奇怪的输出。
我将在此处包含部分输出
ABCD
BAD
CABCD
BAD
CBAD
CBAD
CBAD
CBAD
CBAD
CBAD
C
有人可以帮助我吗?提前致谢
重要编辑: 我下载了 Ubuntu,代码在那里运行顺利,完全没有问题。所以,继续
- MacOSX 10.10.3 和 Xcode 6.3.2 --> 不能正常工作
- Ubuntu 15.04 --> 正常工作
不知道为什么。
【问题讨论】:
-
@CrApHer 你知道它是否返回错误和/如果返回,sem_wait 在 SEM_FAILED 信号量参数上的行为吗?
-
你的线程函数有错误的签名。他们每个人都应该接受
void *类型的参数,即使他们不使用它。实际上,您的编译器应该警告指针类型不匹配。 -
在 Fedora 21 上测试你的代码,我非常可靠地看到每次都打印出序列“BACD\n”,进行了数千次迭代。这是合理的——但不能保证的——行为。我在您的代码中没有看到任何解释您突出显示的意外输出的内容。
-
@Ivano 这是您第一次运行程序时发生的,还是在随后的调用中发生的?
-
@JohnBollinger 我编辑了线程签名,这并没有改变任何东西,但感谢您指出这一点以完成。关于你在 Fedora 上的测试,会不会是在 MacOSX 环境下有些奇怪,而在纯 linux 下结果会如预期?
标签: c concurrency semaphore