Multiple threads waiting for same semaphore - c++

Suppose there are 5 threads waiting for a semaphore
CreateSemaphore(sem_bridgempty,0,1,INFINITE);
WaitForSingleObject(sem_bridgempty, INFINITE);
Now when sem_bridgeempty is signalled, one of the 5 threads will wake up and rest will again wait for sem_bridgeempty to be signalled.Am i right here?
I am implementing one lane bridge problem where there can be vehicles moving from one direction only at a time.Also the capacity of the bridge is fixed at 5.What i have done so far is
unsigned WINAPI enter(void *param)
{
int direction = *((int *)param);
while (1)
{
WaitForSingleObject(sem_bridgecount, INFINITE);
WaitForSingleObject(mut_mutex, INFINITE);
if (curr_direction == -1 || direction == curr_direction)
{
curr_direction = direction;
cars_count++;
std::cout << "Car with direction " << direction << " entered " << GetCurrentThreadId() << std::endl;
ReleaseMutex(mut_mutex);
break;
}
else
{
ReleaseMutex(mut_mutex);
WaitForSingleObject(sem_bridgempty, INFINITE);
}
}
Sleep(5000);
exit1(NULL);
return 0;
}
unsigned WINAPI exit1(void *param)
{
WaitForSingleObject(mut_mutex, INFINITE);
cars_count--;
std::cout << "A Car exited " << GetCurrentThreadId() << std::endl;
ReleaseSemaphore(sem_bridgecount, 1, NULL);
if (cars_count == 0)
{
curr_direction = -1;
std::cout << "Bridge is empty " << GetCurrentThreadId() << std::endl;
ReleaseSemaphore(sem_bridgempty, 1, NULL);
}
ReleaseMutex(mut_mutex);
return 0;
}
int main()
{
sem_bridgecount = CreateSemaphore(NULL, 5, 5, NULL);
sem_bridgempty = CreateSemaphore(NULL, 0, 1, NULL);
mut_mutex = CreateMutex(NULL, false, NULL);
//create threads here
}
Consider the below portion
else
{
ReleaseMutex(mut_mutex);
WaitForSingleObject(sem_bridgempty, INFINITE);
A car is going in direction 1.Now there are three enter requests with direction 2.All 3 will be blocked at WaitForSingleObject(sem_bridgempty, INFINITE);.Now when the bridge goes empty.One of the three will be picked up.The one picked up will again make bridge non empty.Then the other two will still wait for the bridge to go empty even though the direction is same.
So even though there is direction=2 car on the bridge, other cars with the same direction are still waiting for the sem_bridgempty.
I even thought of using sem_bridgempty as an event instead of semaphore(setevent() in exit1() when cars_count=0 and resetevent() in enter() when first car enters).But still all threads don't wake up.

The cleanest option would be to use a critical section and a condition variable.
The ENTER algorithm would look like this:
Claim the critical section.
Call SleepConditionVariableCS in a loop, as shown in Using Condition Variables, until either:
The traffic is going in the right direction and the bridge has capacity left, or
The bridge is empty.
Update the state to represent your car entering the bridge.
Release the critical section.
The EXIT algorithm would look like this:
Claim the critical section.
Update the state to represent your car leaving the bridge.
Release the critical section.
Call WakeConditionVariable.
The condition variable could be an integer whose magnitude represents the number of cars on the bridge and whose sign represents the direction of travel.
If you wanted to avoid condition variables, the simplest solution I could come up with requires one critical section and three auto-reset events: one for each direction of travel, plus one to indicate that the bridge is empty. You will also need a variable representing the number of cars on the bridge.
The ENTER algorithm would look like this:
Using WaitForMultipleObjects, claim the event corresponding to your direction of travel or the event corresponding to the bridge being empty, whichever is available first.
Enter the critical section.
Increment the count to represent your car entering the bridge.
If the count is not at capacity, set the event representing your direction of travel.
Leave the critical section.
The EXIT algorithm would look like this:
Enter the critical section.
Decrement the count to represent your car leaving the bridge.
If the count is zero, set the event indicating that the bridge is empty.
If the count is nonzero, set the event corresponding to your direction of travel.
Release the critical section.

need create objects which most corresponded to task. in current task - we have 2 queues - on both direction. both this queue is FIFO by sense. and we need have ability wake exactly count of entries in queue - not only one or all. the windows semaphore is exactly correspond to this. this is FIFO queue and by call ReleaseSemaphore we can exactly set amount of threads (entries) to wake - this is second parameter of api lReleaseCount. in case event or ConditionVariable we can only wake single or all waiters.
your mistake not in that you select semaphore - this is the best choice for this task. you mistake that you select it for wrong essences - sem_bridgecount, sem_bridgempty - which is not queue by sence at all. you ned have 2 semaphores for 2 directions - HANDLE _hSemaphore[2]; - one semaphore per direction - create it as _hSemaphore[0] = CreateSemaphore(0, 0, MAXLONG, 0) - initial count is 0 (!) and maximum count is unlimited (but can select any value >= 5). when car try enter to bridge in direction and can not, because now another direction is active or no free space on bridge - it must wait on semaphore (in FIFO queue) _hSemaphore[direction]. and when car exit from bridge - he need check current situation on bridge and wake one or another direction on some exactly cars count (n) (not all or single) - so call ReleaseSemaphore(_hSemaphore[direction], n, 0);
in general:
void enter(int direction)
{
EnterCriticalSection(..);
BOOL IsNeedWait = fn(direction);
LeaveCriticalSection(..);
if (IsNeedWait) WaitForSingleObject(_hSemaphore[direction], INFINITE)
}
and
void exit(int direction)
{
EnterCriticalSection(..);
direction = calc_new(direction);
if (int WakeCount = calc_wake_count(direction))
{
ReleaseSemaphore(_hSemaphore[direction], WakeCount, 0);
}
LeaveCriticalSection(..);
}
note that in every enter - car only once enter to CriticalSection and after wait on _hSemaphore[direction] it just enter to bridge without again enter to cs and check conditions. this is because we can calculate exactly cars count (not single or all) and direction in exit - and wake only cars which and must enter to bridge, this will be impossible if use events or conditional variables
despite solution with conditional variables and CS is possible, i think it not best because:
thread after wait in SleepConditionVariableCS - again enter to cs which is absolute not need
we need or wake only single car by WakeConditionVariable when really can multiple cars enter to bridge, or wake all by WakeAllConditionVariable
but in this case several threads in concurrent again try enter to the same cs and only one will be winner, another will be wait here
count of waiting threads can be more than maximum place on bridge (5 in your case) - and some threads will be need begin wait again in loop.
all this can be avoid if correct use semaphore
full working implementation here

Related

How to stop one thread from two parallel threads?

I have a program in which we can monitor 2 objects at same time.
myThread = new thread (thred1, id);
vec.push_back (myThread);
In thred1 function,i use Boolean function to read the stored values from a different vector and it runs parallely like this:
element found 2 -- hj
HUMIDITY-1681692777 DISPLAYED IN RH
element found 1 -- hj
TEMPERATURE--1714636915 IN DEGREE CELSIUS
This keeps on running as that is what my program should do.
I have a case where I need to get ID from the user and stop that particular thread and the other should keep running till I stop it.Can someone help me with that?
void thred1 (int id)
{
bool err = false;
while (stopThread == false)
{
for (size_t i = 0; i < v.size (); i++)
{
if (id == v[i]->id)
{
cout << "element found " << v[i]->id << " -- " << v[i]->name << endl;
v[i]->Read ();
this_thread::sleep_for (chrono::seconds (4));
err = true;
break;
}
}
if (!err)
{
cout << "element not found" << endl;
break;
}
}
}
Suspension
1. Assuming you want to suspend the monitor thread but only temporarily (i.e making any changes) then you can just use a mutex. Lock it before accessing the shared vector and unlock it when you're done, ensuring that only one thread can access the data at a time.
2. You can actively suspend the thread using OS support such as SuspendThread and ResumeThread, in the case of Windows, when it's ready.
Termination
1. You could use an event for each monitor thread, name being linked to the ID would work. At each iteration of the monitor check for the termination event, ending the thread if it's active.
2. Pass some variable to each thread, store them in a map with the thread handle being the key, and similar to the previous option just check the value for each iteration.
3. Store all threads in a map with the handle as key, terminating it directly with OS support.
Honestly there are a ton of ways to do this, the best implementation depends on why exactly you want to stop the monitor thread. Any sort of synchronization object like a mutex should be fine if you're reading from one thread and writing from another. Otherwise, just storing all threads with the internal ID as key and the thread as the value should be fine for terminating monitor threads on demand.

Threading and Mutex

I'm working on a program that simulates a gas station. Each car at the station is it's own thread. Each car must loop through a single bitmask to check if a pump is open, and if it is, update the bitmask, fill up, and notify other cars that the pump is now open. My current code works but there are some issues with load balancing. Ideally all the pumps are used the same amount and all cars get equal fill-ups.
EDIT: My program basically takes a number of cars, pumps, and a length of time to run the test for. During that time, cars will check for an open pump by constantly calling this function.
int Station::fillUp()
{
// loop through the pumps using the bitmask to check if they are available
for (int i = 0; i < pumpsInStation; i++)
{
//Check bitmask to see if pump is open
stationMutex->lock();
if ((freeMask & (1 << i)) == 0 )
{
//Turning the bit on
freeMask |= (1 << i);
stationMutex->unlock();
// Sleeps thread for 30ms and increments counts
pumps[i].fillTankUp();
// Turning the bit back off
stationMutex->lock();
freeMask &= ~(1 << i);
stationCondition->notify_one();
stationMutex->unlock();
// Sleep long enough for all cars to have a chance to fill up first.
this_thread::sleep_for(std::chrono::milliseconds((((carsInStation-1) * 30) / pumpsInStation)-30));
return 1;
}
stationMutex->unlock();
}
// If not pumps are available, wait until one becomes available.
stationCondition->wait(std::unique_lock<std::mutex>(*stationMutex));
return -1;
}
I feel the issue has something to do with locking the bitmask when I read it. Do I need to have some sort of mutex or lock around the if check?
It looks like every car checks the availability of pump #0 first, and if that pump is busy it then checks pump #1, and so on. Given that, it seems expected to me that pump #0 would service the most cars, followed by pump #1 serving the second-most cars, all the way down to pump #(pumpsInStation-1) which only ever gets used in the (relatively rare) situation where all of the pumps are in use simultaneously at the time a new car pulls in.
If you'd like to get better load-balancing, you should probably have each car choose a different random ordering to iterate over the pumps, rather than having them all check the pumps' availability in the same order.
Normally I wouldn't suggest refactoring as it's kind of rude and doesn't go straight to the answer, but here I think it would help you a bit to break your logic into three parts, like so, to better show where the contention lies:
int Station::acquirePump()
{
// loop through the pumps using the bitmask to check if they are available
ScopedLocker locker(&stationMutex);
for (int i = 0; i < pumpsInStation; i++)
{
// Check bitmask to see if pump is open
if ((freeMask & (1 << i)) == 0 )
{
//Turning the bit on
freeMask |= (1 << i);
return i;
}
}
return -1;
}
void Station::releasePump(int n)
{
ScopedLocker locker(&stationMutex);
freeMask &= ~(1 << n);
stationCondition->notify_one();
}
bool Station::fillUp()
{
// If a pump is available:
int i = acquirePump();
if (i != -1)
{
// Sleeps thread for 30ms and increments counts
pumps[i].fillTankUp();
releasePump(i)
// Sleep long enough for all cars to have a chance to fill up first.
this_thread::sleep_for(std::chrono::milliseconds((((carsInStation-1) * 30) / pumpsInStation)-30));
return true;
}
// If no pumps are available, wait until one becomes available.
stationCondition->wait(std::unique_lock<std::mutex>(*stationMutex));
return false;
}
Now when you have the code in this form, there is a load balancing issue which is important to fix if you don't want to "exhaust" one pump or if it too might have a lock inside. The issue lies in acquirePump where you are checking the availability of free pumps in the same order for each car. A simple tweak you can make to balance it better is like so:
int Station::acquirePump()
{
// loop through the pumps using the bitmask to check if they are available
ScopedLocker locker(&stationMutex);
for (int n = 0, i = startIndex; n < pumpsInStation; ++n, i = (i+1) % pumpsInStation)
{
// Check bitmask to see if pump is open
if ((freeMask & (1 << i)) == 0 )
{
// Change the starting index used to search for a free pump for
// the next car.
startIndex = (startIndex+1) % pumpsInStation;
// Turning the bit on
freeMask |= (1 << i);
return i;
}
}
return -1;
}
Another thing I have to ask is if it's really necessary (ex: for memory efficiency) to use bit flags to indicate whether a pump is used. If you can use an array of bool instead, you'll be able to avoid locking completely and simply use atomic operations to acquire and release pumps, and that'll avoid creating a traffic jam of locked threads.
Imagine that the mutex has a queue associated with it, containing the waiting threads. Now, one of your threads manages to get the mutex that protects the bitmask of occupied stations, checks if one specific place is free. If it isn't, it releases the mutex again and loops, only to go back to the end of the queue of threads waiting for the mutex. Firstly, this is unfair, because the first one to wait is not guaranteed to get the next free slot, only if that slot happens to be the one on its loop counter. Secondly, it causes an extreme amount of context switches, which is bad for performance. Note that your approach should still produce correct results in that no two cars collide while accessing a single filling station, but the behaviour is suboptimal.
What you should do instead is this:
lock the mutex to get exclusive access to the possible filling stations
locate the next free filling station
if none of the stations are free, wait for the condition variable and restart at point 2
mark the slot as occupied and release the mutex
fill up the car (this is where the sleep in the simulation actually makes sense, the other one doesn't)
lock the mutex
mark the slot as free and signal the condition variable to wake up others
release the mutex again
Just in case that part isn't clear to you, waiting on a condition variable implicitly releases the mutex while waiting and reacquires it afterwards!

A faster thread blocks slower thread

I'm working on a point cloud viewer, and my design is based on two thread
first thread updates the point cloud data ( about 10 fps)
second thread is a D3D renderer to render the point set to screen (about 90 fps)
so my code looks like this:
std::shared_ptr<PointCloud> pointcloud;
CRITICAL_SECTION updateLock;
void FirstThreadProc()
{
while(true)
{
/* some algorithm processes point cloud, takes time */
EnterCriticalSection(&updateLock);
pointcloud->Update(data,length,...); //also takes time to copy and process
LeaveCriticalSection(&updateLock);
}
}
/*...*/
std::shared_ptr<D3DRenderer> renderer;
void SecondThreadProc()
{
MSG msg = { 0 };
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
EnterCriticalSection(&updateLock);
renderer->Render(pointcloud);
LeaveCriticalSection(&updateLock);
}
}
}
I was thought that the second thread is way more fast than first one, so when first one entered the critical section, the second one is blocked, so the renderer window should freeze now or then. but what i'm observed right now is that the renderer window runs very smooth, camera rotate or zoom in/out, all good, but the first thread is very unstable, its fps is ranging from 10 fps to 1 fps.
I'm thinking about two point cloud buffers, then first thread updates the second buffer when outsides the critical section, then swap two buffers within critical section. Will it work?
As mentioned in this, CRITICAL_SECTION is not provide first-in, first-out(FIFO) ordering. since the second thread is way more fast than the first thread, and its whole loop is critical section, it will enter the critical section right after leave it. This may always in the critical section and keep the first one out of it.
my solution is to put more job of the second thread outside the critical section, then it works fine.

pthread_cond_wait strange behaviour

I'm trying to solve Dining philosophers problem using C++.
Code is compiled with g++ -lpthread.
Entire solution is on philosophers github. Repository contains two cpp files: main.cpp and philosopher.cpp. "Main.cpp" creates mutex variable, semaphore, 5 conditinal variables, 5 forks, and starts philosophers. Semaphore is used only to synchronize start of philosophers. Other parameters are passed to philosophers to solve a problem. "Philosopher.cpp" contains solution for given problem but after few steps deadlock occurs.
Deadlock occurs when philosopher 0 is eating, and philosopher 1 (next to him) wants to take forks. Then, philosopher 1 has taken mutex, and wont give it back until philosopher 0 puts his forks down. Philosopher 0 can't put his forks down because of taken mutex, so we have a deadlock. Problem is in Philosopher::take_fork method, call for pthread_cond_wait(a,b) isn't releasing mutex b. Can't figure out why?
// Taking fork. If eather lef or right fork is taken, wait.
void Philosopher::take_fork(){
pthread_mutex_lock(&mon);
std::cout << "Philosopher " << id << " is waiting on forks" << std::endl;
while(!fork[id] || !fork[(id + 1)%N])
pthread_cond_wait(cond + id, &mon);
fork[id] = fork[(id + 1)%N] = false;
std::cout << "Philosopher " << id << " is eating" << std::endl;
pthread_mutex_unlock(&mon);
}
Please reference to this code for the rest.
Your call to pthread_cond_wait() is fine, so the problem must be elsewhere. You have three bugs that I can see:
Firstly, in main() you are only initialising the first condition variable in the array. You need to initialise all N condition variables:
for(int i = 0; i < N; i++) {
fork[i] = true;
pthread_cond_init(&cond[i], NULL);
}
pthread_mutex_init(&mon, NULL);
Secondly, in put_fork() you have an incorrect calculation for one of the condition variables to signal:
pthread_cond_signal(cond + (id-1)%N); /* incorrect */
When id is equal to zero, (id - 1) % N is equal to -1, so this will try to signal cond - 1, which does not point at a condition variable (it's possible that this pointer actually corrupts your mutex, since it might well be placed directly before cond on the stack). The calculation you actually want is:
pthread_cond_signal(cond + (id + N - 1) % N);
The third bug isn't the cause of your deadlock, but you shouldn't call srand(time(NULL)) every time you call rand() - just call that once, at the start of main().

Win32 threads dying for no apparent reason

I have a program that spawns 3 worker threads that do some number crunching, and waits for them to finish like so:
#define THREAD_COUNT 3
volatile LONG waitCount;
HANDLE pSemaphore;
int main(int argc, char **argv)
{
// ...
HANDLE threads[THREAD_COUNT];
pSemaphore = CreateSemaphore(NULL, THREAD_COUNT, THREAD_COUNT, NULL);
waitCount = 0;
for (int j=0; j<THREAD_COUNT; ++j)
{
threads[j] = CreateThread(NULL, 0, Iteration, p+j, 0, NULL);
}
WaitForMultipleObjects(THREAD_COUNT, threads, TRUE, INFINITE);
// ...
}
The worker threads use a custom Barrier function at certain points in the code to wait until all other threads reach the Barrier:
void Barrier(volatile LONG* counter, HANDLE semaphore, int thread_count = THREAD_COUNT)
{
LONG wait_count = InterlockedIncrement(counter);
if ( wait_count == thread_count )
{
*counter = 0;
ReleaseSemaphore(semaphore, thread_count - 1, NULL);
}
else
{
WaitForSingleObject(semaphore, INFINITE);
}
}
(Implementation based on this answer)
The program occasionally deadlocks. If at that point I use VS2008 to break execution and dig around in the internals, there is only 1 worker thread waiting on the Wait... line in Barrier(). The value of waitCount is always 2.
To make things even more awkward, the faster the threads work, the more likely they are to deadlock. If I run in Release mode, the deadlock comes about 8 out of 10 times. If I run in Debug mode and put some prints in the thread function to see where they hang, they almost never hang.
So it seems that some of my worker threads are killed early, leaving the rest stuck on the Barrier. However, the threads do literally nothing except read and write memory (and call Barrier()), and I'm quite positive that no segfaults occur. It is also possible that I'm jumping to the wrong conclusions, since (as mentioned in the question linked above) I'm new to Win32 threads.
What could be going on here, and how can I debug this sort of weird behavior with VS?
How do I debug weird thread behaviour?
Not quite what you said, but the answer is almost always: understand the code really well, understand all the possible outcomes and work out which one is happening. A debugger becomes less useful here, because you can either follow one thread and miss out on what is causing other threads to fail, or follow from the parent, in which case execution is no longer sequential and you end up all over the place.
Now, onto the problem.
pSemaphore = CreateSemaphore(NULL, THREAD_COUNT, THREAD_COUNT, NULL);
From the MSDN documentation:
lInitialCount [in]: The initial count for the semaphore object. This value must be greater than or equal to zero and less than or equal to lMaximumCount. The state of a semaphore is signaled when its count is greater than zero and nonsignaled when it is zero. The count is decreased by one whenever a wait function releases a thread that was waiting for the semaphore. The count is increased by a specified amount by calling the ReleaseSemaphore function.
And here:
Before a thread attempts to perform the task, it uses the WaitForSingleObject function to determine whether the semaphore's current count permits it to do so. The wait function's time-out parameter is set to zero, so the function returns immediately if the semaphore is in the nonsignaled state. WaitForSingleObject decrements the semaphore's count by one.
So what we're saying here, is that a semaphore's count parameter tells you how many threads are allowed to perform a given task at once. When you set your count initially to THREAD_COUNT you are allowing all your threads access to the "resource" which in this case is to continue onwards.
The answer you link uses this creation method for the semaphore:
CreateSemaphore(0, 0, 1024, 0)
Which basically says none of the threads are permitted to use the resource. In your implementation, the semaphore is signaled (>0), so everything carries on merrily until one of the threads manages to decrease the count to zero, at which point some other thread waits for the semaphore to become signaled again, which probably isn't happening in sync with your counters. Remember when WaitForSingleObject returns it decreases the counter on the semaphore.
In the example you've posted, setting:
::ReleaseSemaphore(sync.Semaphore, sync.ThreadsCount - 1, 0);
Works because each of the WaitForSingleObject calls decrease the semaphore's value by 1 and there are threadcount - 1 of them to do, which happen when the threadcount - 1 WaitForSingleObjects all return, so the semaphore is back to 0 and therefore unsignaled again, so on the next pass everybody waits because nobody is allowed to access the resource at once.
So in short, set your initial value to zero and see if that fixes it.
Edit A little explanation: So to think of it a different way, a semaphore is like an n-atomic gate. What you do is usually this:
// Set the number of tickets:
HANDLE Semaphore = CreateSemaphore(0, 20, 200, 0);
// Later on in a thread somewhere...
// Get a ticket in the queue
WaitForSingleObject(Semaphore, INFINITE);
// Only 20 threads can access this area
// at once. When one thread has entered
// this area the available tickets decrease
// by one. When there are 20 threads here
// all other threads must wait.
// do stuff
ReleaseSemaphore(Semaphore, 1, 0);
// gives back one ticket.
So the use we're putting semaphores to here isn't quite the one for which they were designed.
It's a bit hard to guess exactly what you might be running into. Parallel programming is one of those places that (IMO) it pays to follow the philosophy of "keep it so simple it's obviously correct", and unfortunately I can't say that your Barrier code seems to qualify. Personally, I think I'd have something like this:
// define and initialize the array of events use for the barrier:
HANDLE barrier_[thread_count];
for (int i=0; i<thread_count; i++)
barrier_[i] = CreateEvent(NULL, true, false, NULL);
// ...
Barrier(size_t thread_num) {
// Signal that this thread has reached the barrier:
SetEvent(barrier_[thread_num]);
// Then wait for all the threads to reach the barrier:
WaitForMultipleObjects(thread_count, barrier_, true, INFINITE);
}
Edit:
Okay, now that the intent has been clarified (need to handle multiple iterations), I'd modify the answer, but only slightly. Instead of one array of Events, have two: one for the odd iterations and one for the even iterations:
// define and initialize the array of events use for the barrier:
HANDLE barrier_[2][thread_count];
for (int i=0; i<thread_count; i++) {
barrier_[0][i] = CreateEvent(NULL, true, false, NULL);
barrier_[1][i] = CreateEvent(NULL, true, false, NULL);
}
// ...
Barrier(size_t thread_num, int iteration) {
// Signal that this thread has reached the barrier:
SetEvent(barrier_[iteration & 1][thread_num]);
// Then wait for all the threads to reach the barrier:
WaitForMultipleObjects(thread_count, &barrier[iteration & 1], true, INFINITE);
ResetEvent(barrier_[iteration & 1][thread_num]);
}
In your barrier, what prevents this line:
*counter = 0;
to be executed while this other one is executed by another thread?
LONG wait_count =
InterlockedIncrement(counter);