Unexpected behavior from Semaphore

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • azzmosphere
    New Member
    • Oct 2008
    • 5

    Unexpected behavior from Semaphore

    Hi I have been playing with a bit of code to teach myself how to use semaphores on my MAC OSX, however it does not appear to be working, here is a screen shot of what I am getting:

    1. The value of the semaphors is 0
    1. The value of the semaphors is 0
    Bad file descriptor mutex returned -1

    Here is the code that I have been playing with:

    #include <pthread.h>
    #include <semaphore.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>

    #define NITER 1000000

    int count = 0;
    sem_t *mutex;

    void * ThreadAdd(void * a)
    {

    int value;
    sem_getvalue(mu tex, &value);
    printf("1. The value of the semaphors is %d\n", value);

    int r =0;
    if((r = sem_trywait(mut ex)) != 0)
    {
    fprintf(stderr, "%s mutex returned %d\n",strerror( errno),r);
    exit(EXIT_FAILU RE);
    }

    int i, tmp;
    for(i = 0; i < NITER; i++)
    {
    tmp = count; /* copy the global count locally */
    tmp = tmp+1; /* increment the local copy */
    count = tmp; /* store the local value into the global count */
    }
    sem_post (mutex);

    sem_getvalue(mu tex, &value);
    printf("2. The value of the semaphors is %d\n", value);
    }

    int main(int argc, char * argv[])
    {
    pthread_t tid1, tid2;
    sem_init(mutex, 0, 1);
    //mutex = sem_open("mutex ",O_CREAT, S_IRUSR | S_IWUSR, 10);


    if(pthread_crea te(&tid1, NULL, ThreadAdd, NULL))
    {
    printf("\n ERROR creating thread 1");
    exit(EXIT_FAILU RE);
    }

    if(pthread_crea te(&tid2, NULL, ThreadAdd, NULL))
    {
    printf("\n ERROR creating thread 2");
    exit(EXIT_FAILU RE);
    }

    if(pthread_join (tid1, NULL)) /* wait for the thread 1 to finish */
    {
    printf("\n ERROR joining thread");
    exit(EXIT_FAILU RE);
    }

    if(pthread_join (tid2, NULL)) /* wait for the thread 2 to finish */
    {
    printf("\n ERROR joining thread");
    exit(EXIT_FAILU RE);
    }

    if (count < 2 * NITER)
    printf("\n BOOM! count is [%d], should be %d\n", count, 2*NITER);
    else
    printf("\n OK! count is [%d]\n", count);

    sem_close(mutex );
    //sem_unlink("mut ex");
    pthread_exit(NU LL);
    }


    and here is how I have been compiling the code


    gcc -o filename filename.c -lpthread

    I feel like I am missing something really obvious here but don't know what. Has anybody got any idea's?
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Originally posted by azzmosphere
    pthread_t tid1, tid2;
    sem_init(mutex, 0, 1);
    //mutex = sem_open("mutex ",O_CREAT, S_IRUSR | S_IWUSR, 10);


    if(pthread_crea te(&tid1, NULL, ThreadAdd, NULL))
    {
    So exactly what are the contents of tid1 and tid2?

    I see them defined but never initialized.

    Comment

    • azzmosphere
      New Member
      • Oct 2008
      • 5

      #3
      HI thanks for your response but I have figured out what is going wrong here. I had a look at tid1 and tid2 and re-read the man page fore pthread_create. From what I understand the command "pthread_create (&tid1, NULL, ThreadAdd, NULL)" will initialize tid1 to default values as the attr argument is NULL. The actual problem in the code was that MAC OS does not support POSIX style unamed semaphores but does support the older Mach style which is a counting semaphore therefore the solution was either used named semaphore or the Mach. So I modified the original code to do this:

      #include <pthread.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <errno.h>

      // Mach semaphore
      #include <mach/semaphore.h>
      #include <mach/task.h>


      #define NITER 1000000

      int count = 0;
      semaphore_t sem = 0;

      void * ThreadAdd(void * a)
      {

      semaphore_wait( sem);
      int i, tmp;
      for(i = 0; i < NITER; i++)
      {
      tmp = count; /* copy the global count locally */
      tmp = tmp+1; /* increment the local copy */
      count = tmp; /* store the local value into the global count */
      }
      semaphore_signa l(sem);
      }

      int main(int argc, char * argv[])
      {
      pthread_t tid1, tid2;

      int initialValue = 1;
      semaphore_creat e(mach_task_sel f(), &sem, SYNC_POLICY_FIF O, initialValue);



      if(pthread_crea te(&tid1, NULL, ThreadAdd, NULL))
      {
      printf("\n ERROR creating thread 1");
      exit(EXIT_FAILU RE);
      }

      if(pthread_crea te(&tid2, NULL, ThreadAdd, NULL))
      {
      printf("\n ERROR creating thread 2");
      exit(EXIT_FAILU RE);
      }

      if(pthread_join (tid1, NULL)) /* wait for the thread 1 to finish */
      {
      printf("\n ERROR joining thread");
      exit(EXIT_FAILU RE);
      }

      if(pthread_join (tid2, NULL)) /* wait for the thread 2 to finish */
      {
      printf("\n ERROR joining thread");
      exit(EXIT_FAILU RE);
      }

      if (count < 2 * NITER)
      printf("\n BOOM! count is [%d], should be %d\n", count, 2*NITER);
      else
      printf("\n OK! count is [%d]\n", count);

      pthread_exit(NU LL);
      }

      and sha-bam problem solved.

      Comment

      Working...