C++0X Has No Semaphores? How to Synchronize Threads

C++0x has no semaphores? How to synchronize threads?

You can easily build one from a mutex and a condition variable:

#include <mutex>
#include <condition_variable>

class semaphore {
std::mutex mutex_;
std::condition_variable condition_;
unsigned long count_ = 0; // Initialized as locked.

public:
void release() {
std::lock_guard<decltype(mutex_)> lock(mutex_);
++count_;
condition_.notify_one();
}

void acquire() {
std::unique_lock<decltype(mutex_)> lock(mutex_);
while(!count_) // Handle spurious wake-ups.
condition_.wait(lock);
--count_;
}

bool try_acquire() {
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(count_) {
--count_;
return true;
}
return false;
}
};

Segmentation fault usint semaphores to synchronize 3 threads in C

Running your code in a debugger reveals the location of the seg-fault. With backtrace line 41 or main.c (sem_init(sem1, 0, 1);).

Reading symbols from a.out...done.
(gdb) run
Starting program: /home/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at main.c:41
41 sem_init(sem1, 0, 1);
(gdb) next

Program received signal SIGSEGV, Segmentation fault.
__new_sem_init (sem=0x0, pshared=0, value=1) at sem_init.c:44
44 sem_init.c: No such file or directory.
(gdb) bt
#0 __new_sem_init (sem=0x0, pshared=0, value=1) at sem_init.c:44
#1 0x00000000004008a6 in main () at main.c:41

The issue is that sem1 is an initialised pointer. You need to pass a pointer to an instantiated sem_t object.

sem_t sem1;
sem_t sem2;
sem_t sem3;

Then:

  sem_init( &sem1, 0, 1);
sem_init( &sem2, 0, 0);
sem_init( &sem3, 0, 0);

and change sem1 to &sem1 etc. elsewhere of course.

Note that while that stops your code from seg-faulting, it hangs because neither thread waits on sem1. Probably printA() should wait on sem1 rather then sem2.

Sync threads with Posix Semaphores

You seem to have a workable approach: each thread waits on one semaphore, and later posts another to let the next thread run. For that to work, however, each thread should wait for its semaphore before performing its work (i.e. print its message).

Additionally, it looks like your thread functions are using the wrong semaphores. For printone() to run first, it must wait on the semaphore that you initialize with value 1. For printtwo() to run next, it must wait on whichever semaphore printone() posts to. Similarly, for printthree().

As a secondary matter, if your thread functions are not going to use their argument, then it would be best to pass NULL as the third argument to pthread_create().

Can POSIX named semaphores synchronize threads?

Yes, they synchronize threads.

The Open Group Base Specification Issue 7 clarifies under General Concepts that all semaphores synchronize threads, whether they are POSIX-style (<semaphore.h>) or SysV-style (<sys/sem.h>):

[T]the semaphore lock operation shall cause the calling thread to be blocked and added to the set of threads awaiting the semaphore

Regarding your remark that "unnamed semaphores are either thread- or process-related, but not both", I don't quite know what you mean. Unnamed semaphores may be shared between (parent-child) processes if allocated in shared memory and explicitly initialized as "pshared". However, process-shared or not, unnamed semaphores synchronize individual threads.

(For what it's worth, POSIX mutexes may also be shared between processes.)

Can C++11 condition_variables be used to synchronize processes?

No, those are meant to synchronize threads within one process, not processes.

Interprocess communication is implemented by using shared files. An interprocess mutex or shared memory is just a file (created in your temp folder for instance) to exchange information (data, locks) between two processes. boost::interprocess offers an nice implementation of that (it does not require any link, code is compiled on the fly, you just need to include it).

To synchronize processes, you should have a look at boost::interprocess. It offers synchronization mechanisms. It offers an interprocess semaphore.



Related Topics



Leave a reply



Submit