I have the following simple program involving pthread and semaphore. I am in osx Maverck 10.9. I use a makefile to compile the program (rather than xcode). I use c++11.

#include <pthread.h>
#include <semaphore.h>
#include <cassert>
#include <iostream>

#define ASSERT(a) if(!(a)) abort

using namespace std;

sem_t countMutex;
int myCount=0;

void *doThread(void *data) {
    int *pi = reinterpret_cast<int *>(data);
    sem_wait(&countMutex);
    for(int i =0 ;i < 100; ++i) {
        myCount += 1;
    }
    sem_post(&countMutex);
    pthread_exit( NULL );
}

void LaunchThread() {
    const int kNumThreads = 10;
    pthread_t tids[kNumThreads];
    int threadData[kNumThreads];
    pthread_attr_t attr;
    pthread_t tid;
    int retVal=0;
    retVal = pthread_attr_init(&attr);
    ASSERT(retVal == 0);
    retVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE );
    ASSERT(retVal == 0);
    sem_init(&countMutex, 0, 1);
    myCount = 0;
    for(int i=0; i < kNumThreads; ++i) {
        threadData[i] = i;
        retVal = pthread_create( &tids[i], &attr, &doThread, &threadData[i]);
        if(retVal != 0) {
            cerr << "cannot create thread" << endl;
            return;
        }
    }

    retVal = pthread_attr_destroy(&attr);
    ASSERT(retVal == 0);
    void *status = NULL;
    for(int i=0; i < kNumThreads; ++i) {
        retVal = pthread_join( tids[i], &status);
        if(retVal != 0) {
            cerr << "cannot join ghread " << i << ", " << tids[i] << endl;
            return;
        }
        cout << "completed thread " << i << ", " << tids[i] << endl;
    }
    cout << "value of myCount: " <<  myCount << endl;
    sem_destroy(&countMutex);
    //sem_unlink(&countMutex);
    pthread_exit( NULL );
}
int main( int argc, char **argv) {
    LaunchThread();
    return 0;
}

The makefile for compiling this is

CXX=clang++
CXXFLAGS=-g -Wall -Wno-deprecated -std=c++11 -pthread  -D DEBUG -g3 $(INCLUDES)
LDFLAGS=$(LIBS)

OBJS=main.o
PROG=test

all: $(PROG)


$(PROG): $(OBJS)
$(CXX) -v -o $(PROG) main.o $(LDFLAGS)

%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $<

clean:
rm $(OBJS); rm test

The program ought to have reported a value of 1000 for myCount. But is inconsistent, on multiple runs.

Eg:

completed thread 0, 0x107dca000
completed thread 1, 0x107e4d000
completed thread 2, 0x107ed0000
completed thread 3, 0x107f53000
completed thread 4, 0x107fd6000
completed thread 5, 0x108059000
completed thread 6, 0x1080dc000
completed thread 7, 0x10815f000
completed thread 8, 0x1081e2000
completed thread 9, 0x108265000
value of myCount: 900
有帮助吗?

解决方案

Unnamed POSIX semaphores are not supported on OSX. If you check your return codes you will see sem_init fail with an error along those lines. You need to use named semaphores.

Use sem_open instead of sem_init. Don't use sem_destroy but rather sem_close and sem_unlink.

You will be good to go.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top