I was reading a bit of Mutex and semaphore.
I have piece of code
int func()
{
i++;
return i;
}
i is declared somewhere outside as a global variable.
If i create counting semaphore with count as 3 won't it have a race condition? does that mean i should be using a binary semaphore or a Mutex in this case ?
Can somebody give me some practical senarios where Mutex, critical section and semaphores can be used.
probably i read lot. At the end i am a bit confused now. Can somebody clear the thought.
P.S: I have understood that primary diff between mutex and binary semaphore is the ownership. and counting semaphore should be used as a Signaling mechanism.
Differences between mutex and semaphore (I never worked with CriticalSection):
When using condition variables, its lock must be a mutex.
When using more than 1 available resources, you must use a semaphore initialized with the number of available resources, so when you're out of resources, the next thread blocks.
When using 1 resource or some code that may only be executed by 1 thread, you have the choice of using a mutex or a semaphore initialized with 1 (this is the case for OP's question).
When letting a thread wait until signaled by another thread, you need a semaphore intialized with 0 (waiting thread does sem.p(), signalling thread does sem.v()).
A critical section object is the easiest way here. It is a lightweight synchronisation object.
Here is some code as example:
#define NUMBER_OF_THREADS 100
// global
CRITICAL_SECTION csMyCriticalSectionObject;
int i = 0;
HANDLE hThread[NUMBER_OF_THREADS];
int main(int argc, char *argv[])
{
// initialize the critical section object
InitializeCriticalSection(&csMyCriticalSectionObject);
// create 100 threads:
for (int n = 0; n < NUMBER_OF_THREADS; n++)
{
if (!CreateThread(NULL,0,func,hThread[n],0,NULL))
{
fprintf(stderr,"Failed to create thread\n");
}
}
// wait for all 100 threads:
WaitForMultipleObjects(NUMBER_OF_THREADS,hThread,TRUE,INFINITE);
// this can be made more detailed/complex to find each thread ending with its
// exit code. See documentation for that
}
Links: CreateThread function and WaitForMultipleObjects function
With the thread:
// i is global, no need for i to returned by the thread
DWORD WINAPI func( LPVOID lpvParam )
{
EnterCriticalSection(&csMyCriticalSectionObject);
i++;
LeaveCriticalSection(&csMyCriticalSectionObject);
return GetLastError();
}
Mutex and/or semaphore are going to far for this purpose.
Edit: A semaphore is basically a mutex which can be released multiple times. It stores the number of release operations and can therefore release the same number of waits on it.
Related
I am trying to use mutex to arrange the output between two threads to print the message from Thread 1 then print output from thread 2.
but I am getting the messages to be printed randomly so it seems like I am not using mutex correctly.
std::mutex mu;
void share_print(string msg, int id)
{
mu.lock();
cout << msg << id << endl;
mu.unlock();
}
void func1()
{
for (int i = 0; i > -50; i--)
{
share_print(string("From Func 1: "), i);
}
}
int main()
{
std::thread t1(func1);
for (int i = 0; i < 50; i++)
{
share_print(string("From Main: "), i);
}
t1.join();
return 0;
}
the output is:
Your usage of mutexes is 100% correct. It's your expectation of mutex behavior, and execution thread behavior, that misses the mark. For example, C++ execution threads give you no guarantees whatsoever that any line in func1 will be executed before main() completely finishes executing its for loop.
As far as mutexes are concerned, your only guarantees, that matter here are:
Only one execution thread can lock a given std::mutex at the same time.
If a std::mutex is not locked, one of two things will happen when an execution thread attempts to lock it, either: a) it will lock it b) if another thread already has it locked or manages to lock it first it will block until the mutex is no longer locked, and then it will attempt to lock the mutex again.
It is very important to understand all the implications of these rules. Even if your execution thread has a mutex locked, then proceeds to unlock it, and then lock it again, it may end up re-locking the mutex immediately even if another execution thread is also waiting to lock the mutex. Mutexes do not impose any kind of a queueing, a locking order, or a priority between different execution threads that are trying to lock it. It's a free-for-all.
Even if mutexes worked the way you expected them to work, that still gives you no guarantees whatsoever:
std::thread t1 (func1 );
Your only guarantee here is that func1 will be called by a new execution thread at some point on or after this std::thread object's construction finishes.
for (int i = 0; i < 50; i++)
{
share_print(string("From Main: "), i);
}
This entire for loop can finish even before a single line from func1 gets executed. It'll lock and unlock the mutex 50 times and call it a day, before func1 wakes up and does the same.
Or, alternatively, it's possible for func1 to run to completion before main enters the for loop.
You have no expectations of any order of execution of multiple execution threads, unless explicit syncronization takes place.
In order to achieve your interleaving output a lot more work is needed. In addition to just a mutex there will need to be some kind of a condition variable, and a separate variable that indicates whose "turn" it is. Each execution thread, both main and func1, will not only need to lock the mutex, but block on the condition variable until the shared variable indicates that it's turn is up, then do its printing, set the shared variable to indicate that it's the other thread's turn, signal the condition variable, and only then unlock the mutex (or, always keep the mutex locked and always spin on the condition variable).
I'm new to C++ (on Windows) and threading and I'm currently trying to find a solution to my problem using mutexes, semaphores and events.
I'm trying to create a Barrier class with a constructor and a method called Enter. The class Barrier with it's only method Enter is supposed to hold off any thread that enters it, until a number of thread have reached that method. The number of thread to wait for it recieved at the contructor.
My problem is how do I use the locks to create that effect? what I need is something like a reversed semaphore, that holds threads until a count has been reached and not like the regular semaphore works that lets threads in until a count is reached.
Any ideas as to how to go about this would be great.
Thanks,
Netanel.
Maybe:
In the ctor, store the limit count and create an empty semaphore.
When a thread calls Enter, lock a mutex first so you can twiddle inside safely. Inc a thread count toward the limit count. If the limit has not yet been reached, release the mutex and wait on the semaphore. If the limit is reached, signal the semaphore[limit-1] times in a loop, zero the thread count, (ready for next time), release the mutex and return from Enter(). Any threads that were waiting on the semaphore, and are now ready/running, should just return from their 'Enter' call.
The mutex prevents any released thread that loops around from 'getting in again' until all the threads that called 'Enter' and waited have been set running and the barrier is reset.
You can implement it with condition variable.
Here is an example:
I declare 25 threads and launch them doing the WorkerThread function.
The condition I am checking to block/unblick the threads is whether the number of threads in the section is less than 2.
(I have added some asserts to prove what my coode does).
My code is simply sleeping in the critical section and after I decrease the number of threads in the critical section.
I also added a mutex for the cout to have clean messages.
#include
#include
#include
#include
#include
#include
#include /* assert */
using namespace std;
std::mutex m;
atomic<int> NumThreadsInCritialSection=0;
int MaxNumberThreadsInSection=2;
std::condition_variable cv;
mutex coutMutex;
int WorkerThread()
{
// Wait until main() sends data
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return NumThreadsInCritialSection<MaxNumberThreadsInSection;});
}
assert (NumThreadsInCritialSection<MaxNumberThreadsInSection);
assert (NumThreadsInCritialSection>=0);
NumThreadsInCritialSection++;
{
std::unique_lock<std::mutex> lk(coutMutex);
cout<<"NumThreadsInCritialSection= "<<NumThreadsInCritialSection<<endl;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
NumThreadsInCritialSection--;
{
std::unique_lock<std::mutex> lk(coutMutex);
cout<<"NumThreadsInCritialSection= "<<NumThreadsInCritialSection<<endl;
}
cv.notify_one();
return 0;
}
int main()
{
vector<thread> vWorkers;
for (int i=0;i<25;++i)
{
vWorkers.push_back(thread(WorkerThread));
}
for (auto j=vWorkers.begin(); j!=vWorkers.end(); ++j)
{
j->join();
}
return 0;
}
Hope that helps, tell me if you have any questions, I can comment or change my code.
Pseudocode outline might look like this:
void Enter()
{
Increment counter (atomically or with mutex)
if(counter >= desired_count)
{
condition_met = true; (protected if bool writes aren't atomic on your architecture)
cond_broadcast(blocking_cond_var);
}
else
{
Do a normal cond_wait loop-plus-predicate-check (waiting for the broadcast and checking condition_met each iteration to protect for spurious wakeups).
}
}
Suppose we have two workers. Each worker has an id of 0 and 1. Also suppose that we have jobs arriving all the time, each job has also an identifier 0 or 1 which specifies which worker will have to do this job.
I would like to create 2 threads that are initially locked, and then when two jobs arrive, unlock them, each of them does their job and then lock them again until other jobs arrive.
I have the following code:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
struct job{
thread jobThread;
mutex jobMutex;
};
job jobs[2];
void executeJob(int worker){
while(true){
jobs[worker].jobMutex.lock();
//do some job
}
}
void initialize(){
int i;
for(i=0;i<2;i++){
jobs[i].jobThread = thread(executeJob, i);
}
}
int main(void){
//initialization
initialize();
int buffer[2];
int bufferSize = 0;
while(true){
//jobs arrive here constantly,
//once the buffer becomes full,
//we unlock the threads(workers) and they start working
bufferSize = 2;
if(bufferSize == 2){
for(int i = 0; i<2; i++){
jobs[i].jobMutex.unlock();
}
}
break;
}
}
I started using std::thread a few days ago and I'm not sure why but Visual Studio gives me an error saying abort() has been called. I believe there's something missing however due to my ignorance I can't figure out what.
I would expect this piece of code to actually
Initialize the two threads and then lock them
Inside the main function unlock the two threads, the two threads will do their job(in this case nothing) and then they will become locked again.
But it gives me an error instead. What am I doing wrong?
Thank you in advance!
For this purpose you can use boost's threadpool class.
It's efficient and well tested. opensource library instead of you writing newly and stabilizing it.
http://threadpool.sourceforge.net/
main()
{
pool tp(2); //number of worker threads-currently its 2.
// Add some tasks to the pool.
tp.schedule(&first_task);
tp.schedule(&second_task);
}
void first_task()
{
...
}
void second_task()
{
...
}
Note:
Suggestion for your example:
You don't need to have individual mutex object for each thread. Single mutex object lock itself will does the synchronization between all the threads. You are locking mutex of one thread in executejob function and without unlocking another thread is calling lock with different mutex object leading to deadlock or undefined behaviour.
Also since you are calling mutex.lock() inside whileloop without unlocking , same thread is trying to lock itself with same mutex object infinately leading to undefined behaviour.
If you donot need to execute threads parallel you can have one global mutex object can be used inside executejob function to lock and unlock.
mutex m;
void executeJob(int worker)
{
m.lock();
//do some job
m.unlock();
}
If you want to execute job parallel use boost threadpool as I suggested earlier.
In general you can write an algorithm similar to the following. It works with pthreads. I'm sure it would work with c++ threads as well.
create threads and make them wait on a condition variable, e.g. work_exists.
When work arrives you notify all threads that are waiting on that condition variable. Then in the main thread you start waiting on another condition variable work_done
Upon receiving work_exists notification, worker threads wake up, and grab their assigned work from jobs[worker], they execute it, they send a notification on work_done variable, and then go back to waiting on the work_exists condition variable
When main thread receives work_done notification it checks if all threads are done. If not, it keeps waiting till the notification from last-finishing thread arrives.
From cppreference's page on std::mutex::unlock:
The mutex must be unlocked by all threads that have successfully locked it before being destroyed. Otherwise, the behavior is undefined.
Your approach of having one thread unlock a mutex on behalf of another thread is incorrect.
The behavior you're attempting would normally be done using std::condition_variable. There are examples if you look at the links to the member functions.
I am trying to implement very simple Windows events in Linux. Only for my scenario - 3 threads, 1 main and 2 secondary. Each of secondary threads raise 1 event by SetEvent and main thread wait it. Example:
int main()
{
void* Events[2];
Events[0] = CreateEvent();
Events[1] = CreateEvent();
pthread_start(Thread, Events[0]);
pthread_start(Thread, Events[1]);
WaitForMultipleObjects(2, Events, 30000) // 30 seconds timeout
return 0;
}
int* thread(void* Event)
{
// Do something
SetEvent(Event);
// Do something
}
So, to implement it, i use conditional variables. But my question is - is this a right way? Or i doing something wrong? My implementation:
// Actually, this function return pointer to struct with mutex and cond
// here i just simplified example
void* CreateEvent(mutex, condition)
{
pthread_mutex_init(mutex, NULL);
pthread_cond_init(condition, NULL);
}
bool SetEvent (mutex, condition)
{
pthread_mutex_lock(mutex);
pthread_cond_signal(condition);
pthread_mutex_unlock(mutex);
}
int WaitForSingleObject(mutex, condition, timeout)
{
pthread_mutex_lock(mutex);
pthread_cond_timedwait(condition, mutex, timeout);
pthread_mutex_unlock(mutex);
}
// Call WaitForSingleObject for each event.
// Yes, i know, that its a wrong way, but it should work in my example.
int WaitForMultipleObjects(count, mutex[], condition[], timeout);
And all seems good, but i think, that problem will appear when i call WaitFor.. function in Main thread before SetEvent in secondary thread will be called. In Windows, it worked well, but in Linux - only idea is described above.
Maybe you tell me the better way to solve it? Thank you.
UPD: Timeout is very important, because one of the secondary threads may not pass SetEvent().
Basing this on the description of WaitForSingleObject
The WaitForSingleObject function checks the current state of the specified object. If the object's state is nonsignaled, the calling thread enters the wait state until the object is signaled or the time-out interval elapses.
The difference between that behavior and the code is that the code will always wait on the condition variable, as it does not check a predicate. This introduces synchronization issues between the pthread_condt_timewait and pthread_cond_signal calls.
The general idiom for signalling a condition variable is:
lock mutex
set predicate
unlock mutex
signal condition variable
And when waiting for a condition variable:
lock mutex
while ( !predicate )
{
wait on condition variable
}
unlock mutex
Based on what is trying to be accomplished, a separate bool could be used as a predicate for each Event. By introducing a predicate, WaitForSingleObject should only wait on the condition variable if the Event has not been signaled. The code would look similar to the following:
bool SetEvent (mutex, condition)
{
pthread_mutex_lock(mutex); // lock mutex
bool& signalled = find_signal(condition); // find predicate
signalled = true; // set predicate
pthread_mutex_unlock(mutex); // unlock mutex
pthread_cond_signal(condition); // signal condition variable
}
int WaitForSingleObject(mutex, condition, timeout)
{
pthread_mutex_lock(mutex); // lock mutex
bool& signalled = find_signal(condition); // find predicate
while (!signalled)
{
pthread_cond_timedwait(condition, mutex, timeout);
}
signalled = false; // reset predicate
pthread_mutex_unlock(mutex); // unlock mutex
}
There was similar question on stackoverflow already: WaitForSingleObject and WaitForMultipleObjects equivalent in linux
In addition you can use semaphores:
sem_t semOne ;
sem_t semTwo ;
sem_t semMain ;
In main thread:
sem_init(semOne,0,0) ;
sem_init(semTwo,0,0) ;
sem_init(semMain,0,0) ;
...
sem_wait(&semMain);
// Thread 1
sem_wait(&semOne);
sem_post(&semMain);
// Thread 2
sem_wait(&semTwo);
sem_post(&semMain);
Detailed description and various examples could be found here: ------http://www.ibm.com/developerworks/linux/library/l-ipc2lin3/index.html
The previous link is no longer available. The most recent archived version at The Internet Archive's Wayback Machine is:
https://web.archive.org/web/20130515223326/http://www.ibm.com/developerworks/linux/library/l-ipc2lin3/index.html
I think semaphore is a better solution here, because it can be used inter-process.
You can wrap the interface, if name is not provide, then use pthread_ to initialize it for intra-process to use, which can short the resource usage, but when name used, try to use sem initialize it, for intra-process use.
Let say I have an array of 5 threads :
//main thread
pthread_t t[5];
pthread_mutex_t mutex[5];
queue<int> q[5];
for(int i = 0; i < 5; i++){
pthread_create(&pthread_t[i], NULL, worker, NULL);
}
for(int i = 0; i < 5; i++){
pthread_mutex_lock(&mutex[i]);
queue[i].push_back(i);
pthread_mutex_unlock(&mutex[i]);
}
void* worker(void* arg){
pthread_mutex_lock(&mutex[?]);
}
I am confused with the mutex_lock here. My question is:
How could I let the worker know which mutex to lock?
When I access the mutex through mutex[i], do I need another lock since the child thread might be accessing the mutex array as well?
Thanks.
You need to be clear which threads are sharing which queues. The code you've written suggests each worker thread works on a specific queue, but the main thread (that spawns the workers) will be pushing back new values onto those queues. If that's what you want, then what you've done is basically correct, and you can let the worker threads know the array index of the mutex they're to lock/unlock by casting it to void* and passing it as the argument to pthread_create, which will in turn be passed as a void* to the worker function. You do not need any additional layer of locking around the mutex array - it is entirely safe to access specific elements independently, though if it were say a vector that was being resized at run-time, then you would need that extra level of locking.
Associate the mutex with the queue creating a new struct;
typedef struct {
pthread_mutex_t mutex;
queue<int> q;
} safe_queue;
safe_queue queue_pool [5];
void* worker(safe_queue){
pthread_mutex_lock(&safe_queue.mutex);
}
That last argument to the pthread_create is handed over to the thread when it's called, so you can just pass a value to the specific thread.
Since you want both a specific mutex and a specific queue, you're better off passing in the value of i directly.
for(int i = 0; i < 5; i++){
pthread_create(&pthread_t[i], NULL, worker, (void*)i);
}
void *worker (void *pvI) {
int idx = (int)pvI; // Check for cast problems.
// Use mutex[idx] and q[idx].
}
However, if you want to do it this way, I'd go for a single queue and mutex.
That's because the act of putting something on the queue is almost certainly going to be much faster than processing an item on the queue (otherwise you wouldn't need threads at all).
If you have multiple queues, the main thread has to figure out somehow which are the underutilised threads so it can select the best queue. If you have one queue and one mutex to protect it, the threads will self-organise for efficiency. Those threads that do long jobs won't try to get something from the queue. Those doing short jobs will come back sooner.
I should mention that mutexes on their own are not a good solution for this producer/consumer model. You can't have a thread lock the mutex then wait indefinitely on the queue since that will prevent the main thread putting anything on the queue.
So that means your worker threads will be constantly polling the queues looking for work.
If you use a mutex combined with a condition variable, it will be a lot more efficient. That's because the threads are signalled by the main thread when work is available rather than constantly grabbing the mutex, checking for work, then releasing the mutex.
The basic outline will be, for the main thread:
initialise
while not finished:
await work
lock mutex
put work on queue
signal condvar
unlock mutex
terminate
and, for the worker threads:
initialise
while not finished:
lock mutex
while queue is empty:
wait on condvar
get work from queue
unlock mutex
do work
terminate
Don't pass a NULL pointer as arg to the thread. Instead use a pointer to an object that defines what the thread has to do.
How could I let the worker know which mutex to lock?
Pass the number as the last parameter to pthread_create()
for(int i = 0; i < 5; i++)
{
pthread_create(&pthread_t[i], NULL, worker, reinterpret_cast<void*>(i));
}
Then you can get the value like this:
void* worker(void* arg)
{
int index = reinterpret_cast<int>(arg);
pthread_mutex_lock(&mutex[index]);
}
When I access the mutex through mutex[i], do I need another lock since the child thread might be accessing the mutex array as well?
No. Because the variable mutex itself is never modified. Each member of the array behaves in an atomic fashion via the pthread_mutext_X() methods.
A slightly better design would be:
//main thread
struct ThreadData
{
pthread_mutex_t mutex;
queue<int> queue;
};
pthread_t t[5];
ThreadData d[5];
for(int i = 0; i < 5; i++)
{
pthread_create(&t[i], NULL, worker, &d[i]); // Pass a pointer to ThreadData
}
void* worker(void* arg)
{
// Retrieve the ThreadData object.
ThreadData d = reinterpret_cast<ThreadData*>(arg);
pthread_mutex_lock(&(d.mutex));
<STUFF>
}