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.
Related
I am learning multi-threading in Linux platform. I wrote this small program to get comfort with the concepts. On running the executable, I could not see any error nor does it print Hi. Hence I made to sleep the thread after I saw the output. But still could not see the prints on the console.
I also want to know which thread prints at run time. Can anyone help me?
#include <iostream>
#include <unistd.h>
#include <pthread.h>
using std::cout;
using std::endl;
void* print (void* data)
{
cout << "Hi" << endl;
sleep(10000000);
}
int main (int argc, char* argv[])
{
int t1 = 1, t2 =2, t3 = 3;
pthread_t thread1, thread2, thread3;
int thread_id_1, thread_id_2, thread_id_3;
thread_id_1 = pthread_create(&thread1, NULL, print, 0);
thread_id_2 = pthread_create(&thread2, NULL, print, 0);
thread_id_3 = pthread_create(&thread3, NULL, print, 0);
return 0;
}
Your main thread probably exits and thus the entire process dies. So, the threads don't get a chance to run. It's also possible (quite unlikely but still possible) that you'd see the output from the threads even with your code as-is if the threads complete execution before main thread exits. But you can't rely on that.
Call pthread_join(), which suspends the calling thread until the thread (specified by the thread ID) returns, on the threads after the pthread_create() calls in main():
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
You can also use an array of pthread_t which would allow you to use a for loop over the pthread_create() and pthread_join() calls.
Or exit only the main thread using pthread_exit(0), which would exit only the calling thread and the remaining threads (the ones you created) will continue execution.
Note that your thread function should return a pointer or NULL:
void* print (void* data)
{
cout << "Hi" << endl;
return NULL;
}
Not sure about the high sleeps either right the threads exit, which is unnecessary and would hold the threads from exiting. Probably not something you wanted.
I need one clarification related to the Windows Threads (WEC7). Consider the following sample code. I would like to know whether any memory leak in the code.
In the code snippet MyThread1 creates memory in the heap and passed to MyThread2 and the allocated memory is cleared there.
DWORD WINAPI MyThread2(LPVOID lpVoid)
{
int* b = (int*)lpVoid;
int c = *b;
free(lpVoid);
return 0;
}
DWORD WINAPI MyThread1(LPVOID lpVoid)
{
int count =100;
while(count)
{
int* a = NULL;
a= (int*)malloc(sizeof(int));
*a = count;
CloseHandle(CreateThread(NULL, 0, MyThread2,(LPVOID)a, 0, NULL));
count --;
}
return 0;
}
int main()
{
CreateThread(NULL, 0, MyThread1,NULL, 0, NULL);
// wait here until MyThread1 exits.
return 0;
}
The code you have shown will leak if CreateThread() in MyThread1() fails to create a new thread. You are not checking for that condition so MyThread1() can free the memory it allocated. Other than that, since you are allocating memory in one thread and freeing it in another thread, make sure you are using the multi-threaded version of your compiler's RTL.
There's no leak of memory. The calls to malloc are matched by calls to free.
It is possible the some thread 2 instances have not started to run when thread 1 finishes and the program closes. But at that point the system reclaims memory.
You don't call CloseHandle for thread 1, but then I guess this isn't real code. In the real code you would for sure have to capture the handle for thread 1 so you can wait on it.
HANDLE hThread1 = CreateThread(NULL, 0, MyThread1,NULL, 0, NULL);
WaitForSingleObject(hThread1, INFINITE);
CloseHandle(hThread1);
Note that I've adopted your policy of eliding error checking for simplicity of exposition. Of course in real code you'd add error handling for all API calls.
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.