Recursive synchronization - c++

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.

Related

Abnormal output of windows-thread in c++

i'm new to c++ and experimenting a bit around. I started to create a thread using and the CreateThread-Method. I also pass in a pointer to a struct-method, which references a test-value. So far so good. Now i changed the value BEFORE starting the thread to 0. When i start the program, evrything seems to be working like i expected. But when i change the value also AFTER the CreateThread-Method (to 1), the thread outputs always 1. I expected an output of 0, because i thought that changes to a variable does not affect the thread. Or at least an output of 0 first of all and then 1.
Now i tested something:
If i let the main-thread wait for example 5000ms, then the output of the thread is again always 0. But without it is 1 again.
I hope you can help me with the understanding of that problem.
Here is some code:
struct TESTSTRUCT{
int test;
};
DWORD WINAPI testFunc(void* lpParam){
TESTSTRUCT& params=*((TESTSTRUCT*)lpParam);
int a=params.test;
while(true){
cout << a;
Sleep(5000);
}
return 0;
}
int main(int argc, char *argv[]) {
TESTSTRUCT teststr;
teststr.test=0;
HANDLE myhandle;
myhandle = CreateThread(0, 0, testFunc, &teststr, 0, 0);
Sleep(5000); // If left out, thread outputs always 1!
teststr.test=1;
cout << "main" << teststr.test;
CloseHandle(myhandle);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
See this:
myhandle = CreateThread(0, 0, testFunc, &teststr, 0, 0);
You are passing your teststr by reference to your testFunc. Therefore your main method and your testFunc are operating on the same data. Changing one will affect the other.
To be clear, the way it works is that you are getting the address of teststr, casting it to void*, and then within testFunc you are casting it back to TESTSTRUCT&. This is the same thing as if you just passed teststr to testFunc by reference.
I suppose I should mention that without locking you have a race condition on the output of the thread, no matter what the sleep period is. Make main sleep long enough and in general you'll see your thread print the 'old' value, but there's no guarantee.

Thread safe FIFO / Queue (Multiple producers, one consumer)

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.

Which thread finishes with multithreading?

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.

WaitForMultipleObjects with an array of CWinThread pointers

I have a loop generating threads via AfxBeginThread, which stores the CWinThread pointers in an array. In each iteration, I check the thread is not null and store the thread's handle in another array.
const unsigned int maxThreads = 2;
CWinThread* threads[maxThreads];
HANDLE* handles[maxThreads];
for(unsigned int threadId=0; threadId < maxThreads; ++threadId)
{
threads[threadId] = AfxBeginThread(endToEndProc, &threadId,
0,0,CREATE_SUSPENDED);
if(threads[threadId] == NULL)
{
// die carefully
}
threads[threadId]->m_bAutoDelete = FALSE;
handles[threadId] = &threads[threadId]->m_hThread;
::ResumeThread(handles[threadId]);
}
DWORD result = ::WaitForMultipleObjects(maxThreads, handles[0],
TRUE, 20000*maxThreads);
But WaitForMultipleObjects always returns with WAIT_FAILED, and GetLastError yields 6 for invalid handle. Either the test for the AfxBeginThread return is insufficient to guarantee the thread was created successfully and the handle will be valid, or the handle is becoming invalid before the WaitForMultipleObjects call, which I thought would be prevented by setting m_bAutoDelete to FALSE.
Is there a better way to wait on multiple threads when they are created by AfxBeginThread?
Note that it is fine when maxThreads=1.
handles[0] points to something that has ONE valid handle and some data possibly following it. maxThreads instead suggests that array should have two handles there one after another. Hence the error.
This is what you want instead:
HANDLE handles[maxThreads];
//...
handles[threadId] = threads[threadId]->m_hThread;
//...
WaitForMultipleObjects(maxThreads, handles, ...

Why does Sleep function disable my Mutex

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.