hudac
hudac

Reputation: 2798

semop - is it possible to increment a semaphores (in a set of two), whilst the second semaphore is getting blocked

I have two semaphores that should be changed atomically.

  union semun su;
  struct sembuf sb[2];
  int num = 2;

  semid = semget(num, 3, IPC_CREAT | IPC_EXCL | 0600);

  su.val = 1;
  semctl(semid, 0, SETVAL, su);
  su.val = 0;
  semctl(semid, 1, SETVAL, su);

  sb[0].sem_num = 0;
  sb[0].sem_op  = 1; // signal
  sb[0].sem_flg = 0;

  sb[1].sem_num = 1;
  sb[1].sem_op  = -1; //wait
  sb[1].sem_flg = 0;

  semop(semid, sb, 2)

As you can see, one semaphore should signal(), and the other should wait().

I read in this question that if both of the semaphores are changed at once, and if there is one semaphore that get blocked, then it doesn't really changes the other - and all of the set is going to sleep.

In my implementation it is really important to me that:

  1. Both of the operations of the two semaphores will happen atomically
  2. If the second semaphore will be blocked, it won't matter to the first semaphore. Means that the first semaphore will signal() as supposed to, and the second will wait()...

I couldn't understand from the attached question if it is possible to do, and I'm not sure that there is an answer to that there...

So I wanted to ask if it possible

Thanks ahead

Upvotes: 1

Views: 2112

Answers (2)

Slava
Slava

Reputation: 44248

First of all your code sample is incorrect and does not make much sense. It should be instead:

sb[0].sem_num = 0;
sb[0].sem_op = 1; // signal
sb[0].sem_flg = 0;

sb[1].sem_num = 1;
sb[1].sem_op = -1; //wait
sb[1].sem_flg = 0;

semop(semid, sb, 2)

What you are describing is possible, and that's just 2 sequential operations:

sb[0].sem_num = 0;
sb[0].sem_op = 1; // signal
sb[0].sem_flg = 0;
semop(semid, sb, 1)

sb[0].sem_num = 1;
sb[0].sem_op = -1; // wait
sb[0].sem_flg = 0;
semop(semid, sb, 1)

After discussion in comments it looks like the question could be rephrased like this: can I make semop() atomic operation partially atomic? No you cannot, it is atomic. If you do not need multiple operations to be atomic, do not put them in one semop().

Upvotes: 0

Barath Ravikumar
Barath Ravikumar

Reputation: 5836

I read in this question that if both of the semaphores are changed at once, and if there is one semaphore that get blocked, then it doesn't really changes the other - and all of the set is going to sleep.

What the question deals is whether the set of semaphore operations happens atomically or not. The Answer rightly clarified it to be Atomic.

Instead of thinking this way

"if both of the semaphores are changed at once"

Look at it this way

"if both of the semaphores are changed as one "

I am sure , you will then appreciate the concept of atomicity.

So clearly in the above code doing this

semop(semid, sb, 2)

will perform operations of both the semaphore sb[0] and ab[1] as a single operation , regardless of what your intentions are.

Upvotes: 1

Related Questions