I am trying to debug a multi-threaded program that uses CSemaphore to limit the size of a buffer.
How do you get the current value of the semaphore counter from this class? It doesn't seem to be directly accessed from any of its members, and I can't seem to find any functions that will give me it either.
You're not supposed to care - this is a semaphore, not thread-shared counter.
That said, you might abuse the ReleaseSemaphore API's lpPreviousCount output parameter
BOOL WINAPI ReleaseSemaphore(
__in HANDLE hSemaphore,
__in LONG lReleaseCount,
__out_opt LPLONG lpPreviousCount
);
The idea:
CSemaphore &mySemaphore = /*initialized from somewhere*/;
HANDLE hsem = (HANDLE) mySemaphore; // http://msdn.microsoft.com/en-us/library/f5zcch25.aspx
LONG peeked_count;
::ReleaseSemaphore(hsem, 1 /*can't be 0, sorry!*/, &peeked_count);
Note that unfortunately you'll have to actually release the semaphore (lReleaseCount must be >0)
That is not easily possible. If you really want to do that, all I can think of doing is to try to lock the semaphore manually as many times as possible, until the locking fails, with 0 time-out, and unlocking immediately after that. You will also have to remember the max count. E.g., untested code:
int max_count = 5;
CSemaphore sem (max_count, max_count);
/*...*/
int count = 0;
while (sem.Lock (0))
++count;
for (int i = 0; i != count; ++i)
sem.Unlock(count);
std::cout << "the lock count is " << (max_count - count);
EDIT:
After seeing sehe's solution, I think a better solution would be combination of both:
int max_count = 5;
CSemaphore sem (max_count, max_count);
if (sem.Lock(0))
{
LONG peeked_count;
::ReleaseSemaphore(hsem, 1 /*can't be 0, sorry!*/, &peeked_count);
/* peeked_count has the count */
}
else
{
/* I do not think it is safe to release the semaphore even if just for debugging. */
/* max_count has the count */
}
Related
I'm trying to get my head around Windows API threads and thread control. I briefly worked with threads in Java so I know the basic concepts but something that has worked in Java seems to only work halfway in C++.
What I am trying to do is as follows: 2 threads in one process, sharing a common resource(for this case, the common resource is a pair of two global variables int a, b;).
The first thread should acquire a mutex, use rand() to generate pairs of numbers from 0 to 100 until it gets a pair such that b == 2 * a, then release the mutex.
The second thread should then acquire the mutex, and check if the b == 2 * a condition is true for the given values(printing something like "incorrect" in case it is not), then release the mutex so the first thread can get it back. This process of generating an checking pairs of numbers should be repeated quite a few times, say 500/1000 times.
My code is as follows:
Main:
#define INIT_SEED time(NULL)
#define NUMBER_OF_CHECKS 250
int a = 0;
int b = 1;
HANDLE mutexHandle = CreateMutex(NULL, FALSE, NULL);
int main()
{
HANDLE thread1Handle = CreateThread(NULL, NULL, Thread1Behaviour, NULL, NULL, NULL);
Sleep(50);
HANDLE thread2Handle = CreateThread(NULL, NULL, Thread2Behaviour, NULL, NULL, NULL);
WaitForSingleObject(thread1Handle, INFINITE);
WaitForSingleObject(thread2Handle, INFINITE);
return 0;
}
Thread 1 behavior:
DWORD WINAPI Thread1Behaviour( LPVOID _ )
{
srand(INIT_SEED);
for (int i = 0; i < NUMBER_OF_CHECKS; i++)
{
WaitForSingleObject(mutexHandle, INFINITE);
do
{
b = rand() % 100;
a = rand() % 100;
}
while (b != 2 * a);
cout << i << ".\t" << b << " " << a << endl;
ReleaseMutex(mutexHandle);
Sleep(50);
}
return 0;
}
Thread 2 behavior:
DWORD WINAPI Thread2Behaviour( LPVOID _ )
{
for (int i = 0; i < NUMBER_OF_CHECKS; i++)
{
WaitForSingleObject(mutexHandle, INFINITE);
if (b == 2 * a)
cout << i << ".\t" << b << "\t=\t2 * " << a << endl;
else
cout << i << ".\t" << b << "\t=\t2 * " << a << "\tINCORRECT!!!" << endl;
ReleaseMutex(mutexHandle);
Sleep(50);
}
return 0;
}
The implementation is simple enough(I skipped over the handle validity checks to keep the code short, in case a bad handle could be the cause i can add them in, but I imagine that in case of a bad handle everything should just crash & burn, not work but with incorrect outputs).
I remember for working with threads in Java that i used to sleep for some time to make sure the same thread does not reacquire the mutex. However, when I run the above code, it mainly works as intended however, when the number of checks is big enough, somethimes the first thread gets the mutex 2 times in a row, leading to an output like this:
1. 92 46
2. 66 33
1. 66 = 2 * 33
Which means that at the end, the second thread will end up checking the same pair several times:
249. 80 40
248. 80 = 2 * 40
249. 80 = 2 * 40
I have tried changing the sleep timer value with values between 0 and 250 but this remains the case no matter how large the sleep period is. When I put at least 250 it seems to work about half the time.
Also, if I remove the cout in the first thread, the problem becomes 2-3 times worse, with more botched synchronizations.
And one more thing I noticed is that for a certain configuration of sleep timer and cout/no cout in thread 1, the number of times the mutex is immediately reacquired is the same, so this is completely reproducible(at least for me).
Using logic, I got 2 conflicting conclusions:
Since it MOSTLY works as intended, it might be a synchronization problem, with the way threads "rush" for the mutex as soon as it is available
Since I am able to reproduce this issue in a pretty "deterministic" way, it might mean that it is an issue in the logic of the code
But the above can't both be true at once, so what exactly is the problem here?
EDIT: To clarify the question: I know that mutex is not technically used for order of execution, but in this case, why does it not work as intended and what would be the fix?
Thanks in advance!
As the title says, I'm trying to write a queue that can be written to by multiple threads and read by a single one. As an added difficulty, I need the queue inputs to remain ordered (First In, First Out). This is where I'm lost. Mutexes aren't necessarily waken up in the order that they were locked, so I don't know what I could use in order to achieve what I want? Here is a simple program illustrating what I'm trying to do:
#include "Queue.h"
#include <Windows.h>
#include <fstream>
#include <mutex>
using std::ofstream;
ofstream myFile("result.txt");
Queue<int> myQueue;
DWORD WINAPI WritingThread(LPVOID lpParam);
DWORD WINAPI LockingThread(LPVOID lpParam);
int main()
{
// This thread will block myQueue for 3 seconds
CreateThread(NULL, 0, LockingThread, NULL, 0, NULL);
// During the locked period, I ask myQueue to push numbers from 0 to 49
for (int i = 0; i < 50; i++)
CreateThread(NULL, 0, WritingThread, (LPVOID)new int(i), 0, NULL);
// If the mutex could wake up in order, myQueue would pop up the numbers in order, but it doesn't.
for (int i = 0; i < 50; i++)
myFile << myQueue.pop() << ",";
return EXIT_SUCCESS;
}
DWORD WINAPI LockingThread( LPVOID lpParam )
{
myQueue.lockQueueFor3Seconds();
return 0;
}
DWORD WINAPI WritingThread( LPVOID lpParam )
{
myQueue.push(*(int*)lpParam);
return 0;
}
The code for the class Queue was taken there, see the bottom of the article for full code. All I did was adding the method "lockQueueFor3Seconds" for testing purpose. The method is defined as such:
void lockQueueFor3Seconds()
{
std::unique_lock<std::mutex> mlock(mutex_);
Sleep(3000);
}
The output of that test looks like this:
1,43,39,46,36,44,49,40,35,42,32,31,28,41,27,38,24,23,20,34,19,16,15,12,37,11,7,8,3,33,30,0,45,4,26,18,48,21,47,22,25,17,14,10,6,29,9,2,13,5
As you can see, clearly not ordered. Thanks for your help!
EDIT: I modified the queue so that it attributes a number to each push call representing their order, when the mutex gets unlocked, queue checks to make sure that it's the correct method's turn before adding an element, otherwise it goes back to waiting. Not sure if I implemented this properly, but it seems to work! The complete code can be found there.
It will never work to assign the thread the value to add and expect them to be added in order because you can't force the order the threads execute in.
Instead, have each thread add the next number (whatever it may be) when it runs. Like this:
std::atomic_int counter;
DWORD WINAPI WritingThread( LPVOID lpParam )
{
myQueue.push( counter++ );
return 0;
}
EDIT: It isn't enough that the increment is atomic. The increment AND the push to the queue needs to be a single atomic operation. That means exposing the lock variable outside of the class (it's already public).
std::atomic_int counter;
DWORD WINAPI WritingThread( LPVOID lpParam )
{
unique_lock<mutex> lock(myQueue.m_mutex);
myQueue.push( counter++ );
return 0;
}
That will work if your mutex implementation lets the same thread call it multiple times. Otherwise, you can do something similar to this:
void pushAndIncrement(T& item)
{
std::unique_lock<std::mutex> mlock(mutex_);
queue_.push(item);
++item;
mlock.unlock();
cond_.notify_one();
}
I think your solution (which you say is working) still has a race condition. If there is a context switch after it increments the letter value, but before it increments the counter value inside of push, it will add the letter in the wrong order. It's such a small window, it might be unlikely to happen, but if you put the counter increment inside of the same lock as the push, it will be perfect, everytime.
I am trying to write a class BlockingQueue for producer-consumer style tasks. I'm using WinAPI, but i have a problem with WaitForSingleObject. When i call it on semaphore with value 0, instead of falling asleep it returns -1 (WAIT_FAILED) and GetLastError() gives 183 (ERROR_ALREADY_EXISTS). That makes me no sense, so i think i must be doing something terribly wrong. The method, where appears the problem looks this way:
template<typename elem_t>
elem_t BlockingQueue<elem_t>::pop() {
WaitForSingleObject(_used_sem, INFINITE);
WaitForSingleObject(_mutex, INFINITE);
uint first = _first;
if (++_first == _length)
_first = 0;
_count--;
ReleaseMutex(_mutex);
ReleaseSemaphore(_free_sem, 1, NULL);
return _data[first];
}
both semaphores and the mutex are initialized in the constructor:
template<typename elem_t>
BlockingQueue<elem_t>::BlockingQueue(uint length) {
_data = new elem_t [length];
_length = length;
_count = 0;
_first = 0;
_last = -1;
_mutex = CreateMutex(NULL, false, NULL);
_free_sem = CreateSemaphore(NULL, _length, INFINITE, NULL);
_used_sem = CreateSemaphore(NULL, _count, INFINITE, NULL);
}
Any ideas why i'm getting such strange error?
EDIT: Error 183 was due to wrong error checking, because it got overwritten by another error before calling GetLastError(). After correcting it, it's just 6 (ERROR_INVALID_HANDLE), much more meaningful.
You're not checking the return value of CreateSemaphore. It is likely that it is failing in this case or if it is succeeding it is creating a "impossible" semaphore. This is due to your use of INFINITE for the maximum count parameter. The maximum count argument is a signed long, INFINITE is intended for use with unsigned millisecond duration, and if you interpret as a signed LONG value, you will end up with -1. The documentation states the maximum count value must be above 0. Use LONG_MAX instead of INFINITE when creating your semaphores.
I am new to here and I hope I am doing everything right.
I was wondering how to find out which thread finishes after waiting for one to finish using the WaitForMultipleObjects command. Currently I have something along the lines of:
int checknum;
int loop = 0;
const int NumThreads = 3;
HANDLE threads[NumThreads];
WaitForMultipleObjects(NumThreads, threads, false, INFINITE);
threads[loop] = CreateThread(0, 0, ThreadFunction, &checknum, 0, 0);
It is only supposed to have a max of three threads running at the same time. So I have a loop to begin all three threads (hence the loop value). The problem is when I go through it again, I would like to change the value of loop to the value of whichever thread just finished its task so that it can be used again. Is there any way to find out which thread in that array had finished?
I would paste the rest of my code, but I'm pretty sure no one needs all 147 lines of it. I figured this snippet would be enough.
When the third parameter is false, WaitForMultipleObjects will return as soon as ANY of the objects is signaled (it doesn't need to wait for all of them).
And the return value indicates which object caused it to return. It will be WAIT_OBJECT_0 for the first object, WAIT_OBJECT_0 + 1 for the second, etc.
I am away from my compiler and I don't know of an onlione IDE that works with windows but here is the rough idea of what you need to do.
const int NumThreads = 3;
HANDLE threads[NumThreads];
//create threads here
DWORD result = WaitForMultipleObjects(NumThreads, threads, false, INFINITE);
if(result >= WAIT_OBJECT_0 && result - WAIT_OBJECT_0 < NumThreads){
int index = result - WAIT_OBJECT_0;
if(!CloseHandle(Handles[index])){ //need to close to give handle back to system even though the thread has finished
DWORD error = GetLastError();
//TODO handle error
}
threads[index] = CreateThread(0, 0, ThreadFunction, &checknum, 0, 0);
}
else {
DWORD error = GetLastError();
//TODO handle error
break;
}
at work we do this a bit differently. We have made a library which wraps all needed windows handle types and preforms static type checking (though conversion operators) to make sure you can't wait for an IOCompletionPort with a WaitForMultipleObjects (which is not allowed). The wait function is variadic rather than taking an array of handles and its size and is specialized using SFINAE to use WaitForSingleObject when there is only one. It also takes Lambdas as arguements and executes the corresponding one depending on the signaled event.
This is what it looks like:
Win::Event ev;
Win::Thread th([]{/*...*/ return 0;});
//...
Win::WaitFor(ev,[]{std::cout << "event" << std::endl;},
th,[]{std::cout << "thread" << std::endl;},
std::chrono::milliseconds(100),[]{std::cout << "timeout" << std::endl;});
I would highly recommend this type of wrapping because at the end of the day the compiler optimizes it to the same code but you can't make nearly as many mistakes.
I found code online that displays how to use threads from a tutorial by redKyle. In the 'Race Condition' tutorial, he basically shows how two threads are sent to a function. The objective of the function is to print '.' and '#' in sequence one hundred times each. He provides the code to get this to work, he does NOT provide the code for the mutex. I have modified the code to include the mutex so that to prevent one thread from accessing the variable that holds the last character printed while another thread is accessing it.
I got the code to work. Great! However, I kept changing the sleep value between 1 and 50. The mutex code works fine. However, when i set sleep to 0 (or just comment it out) the mutex no longer works and the values are no longer printed in the correct manner (I no longer see 200 characters of strictly alternating '#' and '.').
The following is the code:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
static char lastChar='#';
//define a mutex
HANDLE mutexHandle = NULL;
//flag to specify if thread has begun
bool threadStarted = false;
void threadProc(int *sleepVal, int *threadID)
{
cout<<"sleepVal: "<<*sleepVal<<endl;
for (int i=0; i<100; i++)
{
char currentChar;
threadStarted = true;
while(!threadStarted){}
//lock mutex
WaitForSingleObject(mutexHandle, INFINITE);
if (lastChar == '#')
currentChar = '.';
else
currentChar = '#';
Sleep(*sleepVal);
lastChar = currentChar;
ReleaseMutex(mutexHandle);
threadStarted = false;
// cout<<"\nSleepVal: "<<*sleepVal<<" at: "<<currentChar;
cout<<currentChar;
}//end for
}//end threadProc
int main()
{
cout<<"Race conditions by redKlyde \n";
int sleepVal1 = 50;
int sleepVal2 = 30;
//create mutex
mutexHandle = CreateMutex(NULL, false, NULL);
//create thread1
HANDLE threadHandle;
threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal1, 0, NULL);
//create thread2
HANDLE threadHandle2;
threadHandle2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal2, 0, NULL);
WaitForSingleObject(threadHandle, INFINITE);
WaitForSingleObject(threadHandle2, INFINITE);
cout<<endl<<endl;
CloseHandle(mutexHandle);
system("pause");
return 0;
}
So my question is: why does setting sleep to 0 void the mutex code.
Take notice that your print statement is not protected by the mutex, so one thread is free to print while the other is free to modify. By not sleeping, you're allowing the scheduler to determine the print order based upon the quantum of the thread.
There are some things wrong:
1) You should not be sleeping inside a held lock. This is almost never correct.
2) Any place your data is shared, you should be guarding with a lock. This means that the print statement should be in the lock, too.
Also, as a tip for future use of mutual exclusion, on Windows the best usermode mutex is the SRWLock followed by the CriticalSection. Use a handle-based synch object is much slower.