2010-11-09 6 views
9

पर अप्रत्याशित परिणाम मैंने सैमफोरों का उपयोग करके पाठकों-लेखकों की समस्या को हल करने के लिए एक सरल कार्यक्रम लिखा था। यह लिनक्स ओएस पर पूरी तरह से चलता है, लेकिन जब मैं इसे अपने मैक ओएसएक्स पर चलाता हूं तो मुझे अप्रत्याशित परिणाम मिलते हैं और मैं यह नहीं समझ सकता कि क्यों।सेमफोरस का उपयोग करने वाला प्रोग्राम लिनक्स पर ठीक चलता है ... मैक ओएसएक्स

मेरे कार्यक्रम:

#include <semaphore.h> 
#include <sys/types.h> 
#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 

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); 
    } 
} 

उत्पादन मैं लिनक्स पर प्राप्त (क्या यह अपेक्षा की जाती है की तरह लग रहे करने के लिए):

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 
... 

मैक 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 
... 
+2

नहीं एक समाधान है, लेकिन कभी भी एक बहु लड़ी प्रणाली एक ही स्थान में ठीक काम करता है (और आप लिनक्स? के विभिन्न धारणाओं की कोशिश की है), लेकिन किसी अन्य स्थान तो मैं एक रेस स्थिति पर शक किया जाएगा में ठीक नहीं। –

उत्तर

13

sem_init कॉल पर त्रुटि रिटर्न की जांच करें; मुझे यकीन है कि आपको ओएस एक्स संस्करण "फंक्शन लागू नहीं किया गया" त्रुटि लौटाएगा।

ऐसा इसलिए है क्योंकि unnamed POSIX semaphores are not implemented on OS X। आपको नामित सेमफोर, या पर्थ्रेड म्यूटेक्स/हालत चर का उपयोग करने की आवश्यकता है।

+1

बहुत बहुत धन्यवाद। मैं उससे अनजान था। –

2

बस पूर्णता के लिए, यहाँ sem_open() और sem_unlink() बजाय sem_init() और sem_destroy() का उपयोग कर एक काम मैक ओएस एक्स संस्करण है।

/* 
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 <semaphore.h> 
#include <sys/types.h> 
#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <stdlib.h> 

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); 
    } 
} 
+0

आपने अपना जीवन बचा लिया है। वास्तव में नहीं बल्कि मूल रूप से। मुझे मैक ओएस एक्स पर सेमफोरस को प्रारंभ करने के तरीके के बारे में कुछ भी नहीं मिला। मुझे विश्वास नहीं है कि वे अज्ञात सेमफोरों का समर्थन नहीं करते हैं ... –