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.
Related
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.
In my app two threads invoke the same recursive function, that should output data to some file. I don't know how I can synchonized this threads to output correct data. I try a few variants with mutex (commented in code using /** n **/), but it doesn't work (output data are mixed from different threads). How can I organize synchronizathion(i should use only WinAPI and std). Pseudocode below:
HANDLE hMutex = CreateMutex(NULL,FALSE, 0);
wchar_t** HelpFunction(wchar_t const* p, int *t)
{
do
{
/**** 1 ****/ //WaitForSingleObject(hMutex, INFINITE);
wchar_t* otherP= someFunction();
if(...)
{
/**** 2 ****/ //WaitForSingleObject(hMutex, INFINITE);
//File's output should be here
//Outputing p
/**** 2 ****/ //ReleaseMutex(hMutex);
}
if(...)
{
HelpFunction(otherP, t);
}
/**** 1 ****/ //ReleaseMutex(hMutex);
}while(...);
}
unsigned int WINAPI ThreadFunction( void* p)
{
int t = 0;
/**** 3 ****/ //WaitForSingleObject(hMutex, INFINITE);
wchar_t** res = HelpFunction((wchar_t *)p, &t);
/**** 3 ****/ //ReleaseMutex(hMutex);
return 0;
}
void _tmain()
{
HANDLE hThreads[2];
hThreads[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunction, L"param1", 0, NULL);
hThreads[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunction, L"param2", 0, NULL);
WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);
}
With Windows API, if it is a single process, you are probably better off using a Critical Section.
There is no need for a WaitForSingleObject on the critical section, you only use that when you are waiting for some data to write if that is going to happen.
And what I guess you are synchronising is the file-write so each thread writes one whole record at a time. (Ensure you flush any buffers).
You will call
EnterCriticalSection
when you get to the sensitive part and
LeaveCriticalSection
at the end of the sensitive part.
and look here for the more details API.
The recursion doesn't matter here as long as you are not holding the "lock" at the point you recurse, i.e. you do not recurse from within your critical section code. When you recurse as with the code shown, it will NOT spawn a new thread. I don't know if you were expecting it to.
I cannot actually see any file I/O in your HelpFunction. I do however see the pointer that you just called t. It is the same pointer for both threads and it is non-const. Therefore if both threads are going to be writing to that int, you may need to synchronise that too. Once again your code does not actually show how that pointer is being used.
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.
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 */
}
Why does the code sample below cause one thread to execute way more than another but a mutex does not?
#include <windows.h>
#include <conio.h>
#include <process.h>
#include <iostream>
using namespace std;
typedef struct _THREAD_INFO_ {
COORD coord; // a structure containing x and y coordinates
INT threadNumber; // each thread has it's own number
INT count;
}THREAD_INFO, * PTHREAD_INFO;
void gotoxy(int x, int y);
BOOL g_bRun;
CRITICAL_SECTION g_cs;
unsigned __stdcall ThreadFunc( void* pArguments )
{
PTHREAD_INFO info = (PTHREAD_INFO)pArguments;
while(g_bRun)
{
EnterCriticalSection(&g_cs);
//if(TryEnterCriticalSection(&g_cs))
//{
gotoxy(info->coord.X, info->coord.Y);
cout << "T" << info->threadNumber << ": " << info->count;
info->count++;
LeaveCriticalSection(&g_cs);
//}
}
ExitThread(0);
return 0;
}
int main(void)
{
// OR unsigned int
unsigned int id0, id1; // a place to store the thread ID returned from CreateThread
HANDLE h0, h1; // handles to theads
THREAD_INFO tInfo[2]; // only one of these - not optimal!
g_bRun = TRUE;
ZeroMemory(&tInfo, sizeof(tInfo)); // win32 function - memset(&buffer, 0, sizeof(buffer))
InitializeCriticalSection(&g_cs);
// setup data for the first thread
tInfo[0].threadNumber = 1;
tInfo[0].coord.X = 0;
tInfo[0].coord.Y = 0;
h0 = (HANDLE)_beginthreadex(
NULL, // no security attributes
0, // defaut stack size
&ThreadFunc, // pointer to function
&tInfo[0], // each thread gets its own data to output
0, // 0 for running or CREATE_SUSPENDED
&id0 ); // return thread id - reused here
// setup data for the second thread
tInfo[1].threadNumber = 2;
tInfo[1].coord.X = 15;
tInfo[1].coord.Y = 0;
h1 = (HANDLE)_beginthreadex(
NULL, // no security attributes
0, // defaut stack size
&ThreadFunc, // pointer to function
&tInfo[1], // each thread gets its own data to output
0, // 0 for running or CREATE_SUSPENDED
&id1 ); // return thread id - reused here
_getch();
g_bRun = FALSE;
return 0;
}
void gotoxy(int x, int y) // x=column position and y=row position
{
HANDLE hdl;
COORD coords;
hdl = GetStdHandle(STD_OUTPUT_HANDLE);
coords.X = x;
coords.Y = y;
SetConsoleCursorPosition(hdl, coords);
}
That may not answer your question but the behavior of critical sections changed on Windows Server 2003 SP1 and later.
If you have bugs related to critical sections on Windows 7 that you can't reproduce on an XP machine you may be affected by that change.
My understanding is that on Windows XP critical sections used a FIFO based strategy that was fair for all threads while later versions use a new strategy aimed at reducing context switching between threads.
There's a short note about this on the MSDN page about critical sections
You may also want to check this forum post
Critical sections, like mutexes are designed to protect a shared resource against conflicting access (such as concurrent modification). Critical sections are not meant to replace thread priority.
You have artificially introduced a shared resource (the screen) and made it into a bottleneck. As a result, the critical section is highly contended. Since both threads have equal priority, that is no reason for Windows to prefer one thread over another. Reduction of context switches is a reason to pick one thread over another. As a result of that reduction, the utilization of the shared resource goes up. That is a good thing; it means that one thread will be finished a lot earlier and the other thread will finish a bit earlier.
To see the effect graphically, compare
A B A B A B A B A B
to
AAAAA BBBBB
The second sequence is shorter because there's only one switch from A to B.
In hand wavey terms:
CriticalSection is saying the thread wants control to do some things together.
Mutex is making a marker to show 'being busy' so others can wait and notifying of completion so somebody else can start. Somebody else already waiting for the mutex will grab it before you can start the loop again and get it back.
So what you are getting with CriticalSection is a failure to yield between loops. You might see a difference if you had Sleep(0); after LeaveCriticalSection
I can't say why you're observing this particular behavior, but it's probably to do with the specifics of the implementation of each mechanism. What I CAN say is that unlocking then immediately locking a mutex is a bad thing. You will observe odd behavior eventually.
From some MSDN docs (http://msdn.microsoft.com/en-us/library/ms682530.aspx):
Starting with Windows Server 2003 with Service Pack 1 (SP1), threads waiting on a critical section do not acquire the critical section on a first-come, first-serve basis. This change increases performance significantly for most code