使用Semaphores的程序在Linux上运行良好…在Mac OSX上出现意外结果

我写了一个简单的程序,使用信号量解决了Readers-Writers问题。 它在Linux操作系统上运行完美,但是当我在Mac OSX上运行时,我得到了意想不到的结果,我无法弄清楚原因。

我的计划:

#include  #include  #include  #include  #include  void* function1(void* val); void* function2(void* val); // shared values volatile int X; volatile int Y; // declare semaphores sem_t s1; sem_t s2; main() { void* status; pthread_t thread1; pthread_t thread2; srand(time(NULL)); // initialize semaphores to zero sem_init(&s1, 0, 0); sem_init(&s2, 0, 0); pthread_create(&thread1, NULL, function1, NULL); pthread_create(&thread2, NULL, function2, NULL); pthread_join(thread1, &status); pthread_join(thread2, &status); sem_destroy(&s1); sem_destroy(&s2); } void* function1(void* val) { while(1) { X = rand()%1000; // write printf("After thread ID A writes to X, X = %d\n", X); sem_post(&s1); // signal sem_wait(&s2); // wait printf("After thread ID A reads from Y, Y = %d\n", Y); // read sleep(3); } } void* function2(void* val) { while(1) { sem_wait(&s1); // wait printf("After thread ID B reads from X, X = %d\n", X); // read Y = rand()%1000; // write printf("After thread ID B write to Y, Y = %d\n", Y); sem_post(&s2); // signal sleep(3); } } 

我在Linux上收到的输出(它应该是什么样子):

 After thread ID A writes to X, X = 100 After thread ID B reads from X, X = 100 After thread ID B write to Y, Y = 234 After thread ID A reads from Y, Y = 234 ... 

Mac OSX上的输出(意外):

 After thread ID A writes to X, X = 253 After thread ID A reads from Y, Y = 0 After thread ID B reads from X, X = 253 After thread ID B write to Y, Y = 728 ... 

检查sem_init调用的错误返回; 我打赌你会发现OS X版本返回“function未实现”错误。

这是因为OS X上没有实现未命名的POSIX信号量 。 您需要使用命名信号量或pthread互斥/条件变量。

为了完整sem_open() ,这是一个使用sem_open()sem_unlink()而不是sem_init()sem_destroy() Mac OS X版本。

 /* cat semtest.c source: "Program using Semaphores runs fine on Linux...unexpected results on Mac osX", http://stackoverflow.com/questions/4136181/program-using-semaphores-runs-fine-on-linux-unexpected-results-on-mac-osx compiled on Mac OS X 10.6.8 with: gcc -ansi -pedantic -std=gnu99 -Os -Wall -Wextra -Wshadow -l pthread -o semtest semtest.c ./semtest */ #include  #include  #include  #include  #include  #include  void* function1(); void* function2(); // shared values volatile int X; volatile int Y; // declare semaphores //sem_t s1; //sem_t s2; sem_t *s1; sem_t *s2; static const char *semname1 = "Semaphore1"; static const char *semname2 = "Semaphore2"; int main(void) { void* status; pthread_t thread1; pthread_t thread2; srand(time(NULL)); /* // initialize semaphores to zero sem_init(&s1, 0, 0); sem_init(&s2, 0, 0); */ s1 = sem_open(semname1, O_CREAT, 0777, 0); if (s1 == SEM_FAILED) { fprintf(stderr, "%s\n", "ERROR creating semaphore semname1"); exit(EXIT_FAILURE); } s2 = sem_open(semname2, O_CREAT, 0777, 0); if (s2 == SEM_FAILED) { fprintf(stderr, "%s\n", "ERROR creating semaphore semname2"); exit(EXIT_FAILURE); } pthread_create(&thread1, NULL, function1, NULL); pthread_create(&thread2, NULL, function2, NULL); pthread_join(thread1, &status); pthread_join(thread2, &status); //sem_destroy(&s1); //sem_destroy(&s2); sem_unlink(semname1); sem_unlink(semname2); return 0; } void* function1() { while(1) { X = rand()%1000; // write printf("After thread ID A writes to X, X = %d\n", X); //sem_post(&s1); // signal //sem_wait(&s2); // wait sem_post(s1); // signal sem_wait(s2); // wait printf("After thread ID A reads from Y, Y = %d\n", Y); // read sleep(3); } } void* function2() { while(1) { //sem_wait(&s1); // wait sem_wait(s1); // wait printf("After thread ID B reads from X, X = %d\n", X); // read Y = rand()%1000; // write printf("After thread ID B write to Y, Y = %d\n", Y); //sem_post(&s2); // signal sem_post(s2); // signal sleep(3); } }