South Park
South Park

Reputation: 33

simple testing of semaphores

I am trying to create a simple program to test semaphores. I am forking the process and tormenting the value of variable c in the critical section of each process, but the value of c I get is still 1 not 2. Even with the mmap() uncommented. Can anyone please explain to me what I am doing wrong? Any help would be appreciated. I am a total newbie in this. Thank you very much for your time.

int main()
{
int c = 0;
  sem_t mutex;
 sem_t mutex1;
 //  sem_t *mutex = (sem_t*)mmap(NULL, sizeof(sem_t*), PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1, 0);
 sem_init(&mutex, 0, 1);
 sem_init(&mutex1, 0, 1);

  pid_t i;
  int id = fork();
 if(id == -1)   {}
  else if(id == 0)
    {
    sem_wait (&mutex);  
   c++;
   sem_post (&mutex);
   }
   else
  {
    sem_wait (&mutex);  
   c++;
   sem_post (&mutex);
   }    
     cout<<c<<endl;
   //system("pause");
   return 0;
    }

I tried it another way by making the pshared argument 1, but it still does not work. I have also tried it sem_op but it still does not work.

 int main()
    {


      int c = 0;


           int sid =semget(1105,2, 0666 | IPC_CREAT);


        pid_t i;
      int id = fork();

       if(id == -1)
       {

        }
            else if(id == 0)
           {

                struct sembuf sb;
                sb.sem_num = 0;
                sb.sem_op = -1;
                sb.sem_flg = 0;
                  if((semop(sid, &sb, 1)) == -1)
            cout<<"error"<<endl;

                    c++;

                sb.sem_num = 0;
                sb.sem_op = -1;
                sb.sem_flg = 0;

                      if((semop(sid, &sb, 1)) == -1)
          cout<<"error"<<endl;

         }
         else if(id == 1)
         {

                   struct sembuf sb;

                  if((semop(sid, &sb, 1)) == -1)
            cout<<"error"<<endl;

                    c++;


                     sb.sem_num = 0;
                    sb.sem_op = -1;
                    sb.sem_flg = 0;

                      if((semop(sid, &sb, 1)) == -1)
          cout<<"error"<<endl;

          }

            cout<<c<<endl;

          return 0;

            }

Upvotes: 0

Views: 1058

Answers (2)

pilcrow
pilcrow

Reputation: 58691

Your primary misstep is that the variable c is not itself shared — each process operates on its own copy of the variable. You want something like this:

int *c;

c = mmap(NULL, sizeof(*c), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
*c = 0;

// ... later ...
++*c;

Additionally, with respect to your sem_init() example, you should:

  • Allocate shared memory of the correct size: sizeof(sem_t) and not sizeof(sem_t*)
  • Set the pshared flag during sem_init()

You likely don't need conditional logic differentiating parent from child after the fork(). After all, you want them to do the same thing.

(Separately, please do not name a POSIX semaphore "mutex." That name will mislead hurried, POSIXly-minded folk who will think you are referring to a different kind of synchronization primitive.)

With respect to your semget() example, you appear to be waiting on the semaphore twice (sb.sem_op = -1) in the child process. The post-fork() check for the parent is incorrect — you check if the returned PID is 1 (which it will never be on a typical UNIX system) rather than if the returned PID is > 0. (Again, however, you likely don't need to have parent and child do different things here.)

Upvotes: 0

Archie
Archie

Reputation: 2672

If you use fork() you have to share the semaphores between the forked processes. See sem_init() manual for more details.

Alternatively you can use a named semaphore, see sem_open() for details, and also a good article on the subject.

Upvotes: 1

Related Questions