Difference Between Completion Variables and Semaphores

Difference between completion variables and semaphores

There are two reasons you might want to use a completion instead of a semaphore. First, multiple threads can wait for a completion, and they can all be released with one call to complete_all(). It's more complex to have a semaphore wake up an unknown number of threads.

Second, if the waiting thread is going to deallocate the synchronization object, there is a race condition if you're using semaphores. That is, the waiter might get woken up and deallocate the object before the waking thread is done with up(). This race doesn't exist for completions. (See Lasse's post.)

What does polling a variable mean?


What does polling a variable mean??

Typically the word "polling" isn't used on a variable per se, but on some resource -- you poll a socket to see if it can be read.

In general though, polling means asking, in a loop, "Ready?" "No" "Ready?" "No" "Ready?" "Yes"

While using semaphores for synchronization does busy waiting indicate checking for a variable continuously or polling of variable. What is the difference between the two(if there is any)

Since the terminology doesn't really apply (a Google search for 'polling variable' yielded nothing interesting) I have to say that yes, they mean the same thing.

In a busy-loop, the CPU is continuously checking a variable ("busy-waiting") to see if it meets some criteria. For waiting on a semaphore, this criteria is whether the value is greater than zero.

Difference between semaphore count and operation value which is passed during semop call

Query 1:

The sem_op can be more than one. In that case, that number is added to the permits the semaphore has

Query 2:

You assumption on query 1 is wrong. It is not the absolute number of permits but the addition to the number of those. The meaning of 'semaphore permit' is how many entities can hold that semaphore simultaneously. This means for example, that if you have 5 threads competing on a critical section protected by a semaphore with 3 permits, only 3 will be able to get in simultaneously.

From the manual:

The variable sem_op specifies one of three semaphore operations:

1. If sem_op is a negative integer and the calling process has alter permission, one of the following shall occur:

* If semval(see <sys/sem.h>) is greater than or equal to the absolute value of sem_op, the absolute value of sem_op is subtracted from sem‐
val. Also, if (sem_flg &SEM_UNDO) is non-zero, the absolute value of sem_op shall be added to the semadj value of the calling process for
the specified semaphore.

* If semval is less than the absolute value of sem_op and (sem_flg &IPC_NOWAIT) is non-zero, semop() shall return immediately.

* If semval is less than the absolute value of sem_op and (sem_flg &IPC_NOWAIT) is 0, semop() shall increment the semncnt associated with
the specified semaphore and suspend execution of the calling thread until one of the following conditions occurs:

-- The value of semval becomes greater than or equal to the absolute value of sem_op. When this occurs, the value of semncnt associated
with the specified semaphore shall be decremented, the absolute value of sem_op shall be subtracted from semval and, if (sem_flg
&SEM_UNDO) is non-zero, the absolute value of sem_op shall be added to the semadj value of the calling process for the specified sema‐
phore.

-- The semid for which the calling thread is awaiting action is removed from the system. When this occurs, errno shall be set to [EIDRM]
and −1 shall be returned.

-- The calling thread receives a signal that is to be caught. When this occurs, the value of semncnt associated with the specified sema‐
phore shall be decremented, and the calling thread shall resume execution in the manner prescribed in sigaction().

2. If sem_op is a positive integer and the calling process has alter permission, the value of sem_op shall be added to semval and, if (sem_flg
&SEM_UNDO) is non-zero, the value of sem_op shall be subtracted from the semadj value of the calling process for the specified semaphore.

3. If sem_op is 0 and the calling process has read permission, one of the following shall occur:

* If semval is 0, semop() shall return immediately.

* If semval is non-zero and (sem_flg &IPC_NOWAIT) is non-zero, semop() shall return immediately.

* If semval is non-zero and (sem_flg &IPC_NOWAIT) is 0, semop() shall increment the semzcnt associated with the specified semaphore and sus‐
pend execution of the calling thread until one of the following occurs:

-- The value of semval becomes 0, at which time the value of semzcnt associated with the specified semaphore shall be decremented.

-- The semid for which the calling thread is awaiting action is removed from the system. When this occurs, errno shall be set to [EIDRM]
and −1 shall be returned.

-- The calling thread receives a signal that is to be caught. When this occurs, the value of semzcnt associated with the specified sema‐
phore shall be decremented, and the calling thread shall resume execution in the manner prescribed in sigaction().

Upon successful completion, the value of sempid for each semaphore specified in the array pointed to by sops shall be set to the process ID of the
calling process. Also, the sem_otime timestamp shall be set to the current time, as described in Section 2.7.1, IPC General Description.

Difference between Counting and Binary Semaphores

Actually, both types are used to synchronize access to a shared resource, whether the entity which is trying to access is a process or even a thread.

The difference is as follows:

Binary semaphores are binary, they can have two values only; one to represent that a process/thread is in the critical section(code that access the shared resource) and others should wait, the other indicating the critical section is free.

On the other hand, counting semaphores take more than two values, they can have any value you want.
The max value X they take allows X process/threads to access the shared resource simultaneously.

For further information, take a look at this link.

http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:semaphores_mutexes

EDIT

The max value that a counting semaphore can take is the the number of processes you want to allow into the critical section at the same time.

Again, you might have a case where you want exclusion over a certain resource, yet you know this resource can be accessed by a max number of processes (say X), so you set a counting semaphore with the value X.

This would allow the X processes to access that resource at the same time; yet the process X+1 would have to wait till one of the processes in the critical section gets out.

Why does DispatchSemaphore.wait() block this completion handler?

From the documentation for NETunnelProviderManager loadAllFromPreferences:

This block will be executed on the caller’s main thread after the load operation is complete

So we know that the completion handler is on the main thread.

We also know that the call to DispatchSemaphore wait will block whatever thread it is running on. Given this evidence, you must be calling all of this code from the main thread. Since your call to wait is blocking the main thread, the completion handler can never be called because the main thread is blocked.

This is made clear by your attempt to call wait on some global background queue. That allows the completion block to be called because your use of wait is no longer blocking the main thread.

And your attempt to call loadAllFromPreferences from a global background queue doesn't change anything because its completion block is still called on the main thread and your call to wait is still on the main thread.

It's a bad idea to block the main thread at all. The proper solution is to refactor whatever method this code is in to use its own completion handler instead of trying to use a normal return value.

Wait for completion block of writeImageToSavedPhotosAlbum by semaphore

Do not wait. Never, never do what you are doing. You are failing to understand what "asynchronous" is about. It means that you are called back when it's all over in the completion block. So that is where you perform the next step.

Do NOT try to return a value from a method that obtains that value in an asynchronous completion block.

So, here, in writeImageToSavedPhotosAlbum:'s completion block, that is where you receive retAssestURL. So if there is a further step, now do it, there, in the completion block. This could involve calling another method or whatever you like, but the point is, things will now happen in the correct order.

And above all, Do NOT use semaphores (or other trickery) to try to turn asynchronous into synchronous. Asynchronous things are asynchronous for a reason. Use the framework, don't fight it. (Actually, what you are doing with semaphores here is not just fighting the framework but spitting in its eye.)

Semaphore wait() and signal()

I think it's an inaccuracy in your source. Atomic for the wait() operation means each iteration of it is atomic, meaning S-- is performed without interruption, but the whole operation is interruptible after each completion of S-- inside the while loop.



Related Topics



Leave a reply



Submit