Why does the thread synchronization not work? - c++

I have written a multithreaded program, in which three threads are trying to save the text to the same file. I applied the critical section. And under windows 7 works perfectly but in CE 6.0 does not sync, ie, each thread is trying at the same time to save:
It works now!!! Thanks Everyone for help!
Critical section:
InitializeCriticalSection(&CriticalSection);
// Create worker threads
for( i=0; i < THREADCOUNT; i++ )
{
aThread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) WriteToFile, NULL, 0, &ThreadID);
if( aThread[i] == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return 1;
}
}
// Wait for all threads to terminate
for( i=0; i < THREADCOUNT; i++ )
{
WaitResult = WaitForSingleObject(aThread[i], INFINITE);
switch(WaitResult)
{
case WAIT_OBJECT_0:
printf("Thread %d has terminated...\n", i);
break;
// Time out
case WAIT_TIMEOUT:
printf("The waiting is timed out...\n");
break;
// Return value is invalid.
default:
printf("Waiting failed, error %d...\n", GetLastError());
ExitProcess(0);
}
}
// Close thread handles
for( i=0; i < THREADCOUNT; i++ )
CloseHandle(aThread[i]);
// Release resources used by the critical section object.
DeleteCriticalSection(&CriticalSection);
Function called by a thread:
DWORD WINAPI WriteToFile( LPVOID lpParam )
{
// lpParam not used in this example
UNREFERENCED_PARAMETER(lpParam);
DWORD dwCount=1, dwWaitResult;
HANDLE hFile;
char DataBuffer[30];
DWORD dwBytesToWrite;
DWORD dwBytesWritten;
// Request ownership of the critical section.
EnterCriticalSection(&CriticalSection);
// Write to the file
printf("Thread %d writing to file...\n", GetCurrentThreadId());
hFile = CreateFile(TEXT("file.txt"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetFilePointer(hFile, 0, NULL, FILE_END);
while( dwCount <= 3 )
{
sprintf(DataBuffer, "Theard %d writing %d\n", GetCurrentThreadId(), dwCount);
dwBytesToWrite = (DWORD)strlen(DataBuffer);
WriteFile( hFile, DataBuffer, dwBytesToWrite, &dwBytesWritten, NULL);
printf("Theard %d wrote %d successfully.\n", GetCurrentThreadId(), dwCount);
}
}
dwCount++;
}
CloseHandle(hFile);
// Release ownership of the critical section.
LeaveCriticalSection(&CriticalSection);
return TRUE;
}

The problem is that you are passing TRUE to the fWaitAll flag for WaitForMultipleObjects. On Windows CE, this is not supported: the documentation on MSDN says that this flag must be FALSE. WaitForMultipleObjects is thus not waiting, but returning an error instead, but you are not checking the return code. The main thread thus goes straight through, closes the handles and deletes the critical section whilst the "worker" threads are still running. Once DeleteCriticalSection has been called, the critical section "can no longer be used for synchronization", so the EnterCriticalSection calls probably no longer block, and you end up with the scenario you have here.
On Windows 7, everything works because the WaitForMultipleObjects call does indeed wait for all the threads to finish.
Rather than using WaitForMultipleObjects, just use WaitForSingleObject in a loop to wait for each thread in turn.

Related

Call a function from a thread and RS 232

I am programming in Visual Studio 2008 in console application. I am working with a display that is communicated by Rs 232.
I have a thread that counts from 0 to 10 seconds. When reaches 10 I want to turn off the displays backlight. For that I have a function that is called from the thread. The called from the thread is well because I know that the code of the function is executed.
But code of turning the backlight off does not work when the function is called from the thread and it works the it is called from another place. Any ideas?
Thanks.
void FunctionBacklightoff(HANDLE portHandle,DWORD bytesTransmitted)
{
cout << "backoff";
WriteFile(portHandle, backlight_off , 4, &bytesTransmitted, NULL);//does not work when
//it is called from the thread. It works when it is called from wmain()
}
DWORD WINAPI solo_thread(void* arg)
{
int Counter = 0;
printf( "In second thread...\n" );
while ( true )
{
if(Counter<10)
{
Counter++;
Sleep(1000);
}
else
{
printf( "Han pasado 10 segundos; Counter:-> %d\n", Counter );
FunctionBacklightoff(portHandle,bytesTransmitted);//from here doesnt work
Counter = 0;
}
}
return 0;
}
int wmain(void)
{
hThread =CreateThread(NULL, 0, solo_thread,NULL ,0, NULL);
//inicialize rs232 communications...
retVal = PortOpen(&portHandle, 115200);
if (!retVal)
{
printf("Could not open CoM port");
getchar();
}
else
{
printf("CoM port opened successfully");
retVal = FALSE;
}
FunctionBacklightoff(portHandle,bytesTransmitted);//from here works
}
How portHandle is declared? Looks like it's static field so thread could simply not get change that happen after it's creation. To be sure you could mark portHandle as volatile or change the order of operations:
//Open port so we will be sure that postHandle is populated before thread starts.
retVal = PortOpen(&portHandle, 115200);
hThread = CreateThread(NULL, 0, solo_thread,NULL ,0, NULL);
Also you have a BUG that your wmain will exit before thread being executed. To fix that you should place following code right before wmain last bracket:
WaitForSingleObject(hThread, INFINITE);
Note that because your thread have while(true) without break condition it will run forever and each 10 seconds will switch off backlight. If this was not intentional add a break into else.

How to directly "assign" a process to a semaphore using windows API?

I'm using the following code from Microsoft as a template:
#include <windows.h>
#include <stdio.h>
#define MAX_SEM_COUNT 10
#define THREADCOUNT 12
HANDLE ghSemaphore;
DWORD WINAPI ThreadProc( LPVOID );
int main( void )
{
HANDLE aThread[THREADCOUNT];
DWORD ThreadID;
int i;
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
ghSemaphore = CreateSemaphore(
NULL, // default security attributes
MAX_SEM_COUNT, // initial count
MAX_SEM_COUNT, // maximum count
NULL); // unnamed semaphore
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
return 1;
}
// Create worker threads
for( i=0; i < THREADCOUNT; i++ )
{
aThread[i] = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
if( aThread[i] == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return 1;
}
}
// Wait for all threads to terminate
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
// Close thread and semaphore handles
for( i=0; i < THREADCOUNT; i++ )
CloseHandle(aThread[i]);
CloseHandle(ghSemaphore);
return 0;
}
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
// lpParam not used in this example
UNREFERENCED_PARAMETER(lpParam);
DWORD dwWaitResult;
BOOL bContinue=TRUE;
while(bContinue)
{
// Try to enter the semaphore gate.
dwWaitResult = WaitForSingleObject(
ghSemaphore, // handle to semaphore
0L); // zero-second time-out interval
switch (dwWaitResult)
{
// The semaphore object was signaled.
case WAIT_OBJECT_0:
// TODO: Perform task
printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
bContinue=FALSE;
// Simulate thread spending time on task
Sleep(5);
// Release the semaphore when task is finished
if (!ReleaseSemaphore(
ghSemaphore, // handle to semaphore
1, // increase count by one
NULL) ) // not interested in previous count
{
printf("ReleaseSemaphore error: %d\n", GetLastError());
}
break;
// The semaphore was nonsignaled, so a time-out occurred.
case WAIT_TIMEOUT:
printf("Thread %d: wait timed out\n", GetCurrentThreadId());
break;
}
}
return TRUE;
}
And I want to adapt it so instead of being the threads the ones that determine how the semaphore fills, it's done by processes, meaning that the semaphore will fill if there are processes running and/or with any of their habdles not closes, and indeed I sort of have done it by changing the working of the thread function with this new function.
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
// lpParam not used in this example
UNREFERENCED_PARAMETER(lpParam);
DWORD dwWaitResult;
BOOL bContinue=TRUE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
while(bContinue)
{
// Try to enter the semaphore gate.
dwWaitResult = WaitForSingleObject(
ghSemaphore, // handle to semaphore
0L); // zero-second time-out interval
CreateProcess("arbol.exe",NULL,NULL,NULL,0,0,NULL,NULL,&si,&pi);
WaitForSingleObject(pi.hProcess,INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
switch (dwWaitResult)
{
// The semaphore object was signaled.
case WAIT_OBJECT_0:
// TODO: Perform task
printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
bContinue=FALSE;
// Simulate thread spending time on task
Sleep(5);
// Release the semaphore when task is finished
if (!ReleaseSemaphore(
ghSemaphore, // handle to semaphore
1, // increase count by one
NULL) ) // not interested in previous count
{
printf("ReleaseSemaphore error: %d\n", GetLastError());
}
break;
// The semaphore was nonsignaled, so a time-out occurred.
case WAIT_TIMEOUT:
printf("Thread %d: wait timed out\n", GetCurrentThreadId());
break;
}
}
return TRUE;
}
With that, although what determines the filling of the semaphore is the thread, in a practical sense it is determined by the complete execution and closing of the handles of the process.
But this looks as a lame way to solve this problem and I bet doing it this way is likely to give problems in the future if extra things are needed from those processes.
How can I create a semaphore so what would really determine the filling of the semaphore would be the processes? To clarify, this would be one possible solution that I don't think it is possible anyhow.
Let's consider that you could Create a Process by something like this:
aThread[i] = CreateProcess(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
Then LPTHREAD_START_ROUTINE would be equivalent in its working but for processes.
Semaphores are supposed to support Interprocess Synchronization in Windows API, but I cannot find any example that specifically uses processes, and I don't get the idea of how could it be done.
Any idea on how to achieve what I want?
Regards.
You want a named semaphore. Where each process shares the semaphore by creating it with the same name.
Create a named semaphore. Same as you have before, but that last parameter gets a string passed to it:
HANDLE hSemaphore = CreateSemaphore(NULL,
MAX_SEM_COUNT,
MAX_SEM_COUNT,
L"TheSemaphoreForMyApp");
Child processes, upon being started, can attach to that same semaphore and get a handle to it by using OpenSemaphore.
HANDLE hSemaphore = OpenSemaphore(EVENT_ALL_ACCESS,
FALSE,
L"TheSemaphoreForMyApp");
You don't have to hardcode a string as the semaphore name. The parent process can create a unique name each time, and then passes that name (e.g. command line parameter) to the child process. That will allow for multiple instances of your program with child processes to cooperate.

Remote Process does not start

I'm trying to call a process from another program, this process being one I've injected via DLL. The first one, where we load the library "Client.dll" works perfectly, this is sown by the MessageBox Debug in DllMain (DLL_PROCESS_ATTACH).
Once the DLL is loaded into the program, I try to call the function MainThread from Client.dll this however using the same method (copied, pasted, edited) doesn't work. Both are posted below, can anyone tell me why? I have removed all code from MainThread but that for debug reasons.
Here is Main Thread:
void MainThread(void * Arguments)
{
MessageBoxA(NULL, "MainThread Started!", "bla", MB_OK); //Not Shown
for (;;)
{
//This loop is here for the main program loop.
}
_endthread();
}
Here is how I load Client.dll and try to call Main Thread, keep in mind the actual injection works but not the starting of Main Thread.
bool InjectDLL(DWORD ProcessID, const char* Path)
{
HANDLE Handle = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID);
if (!Handle)
{
std::cout << "Could not access process! Inject Failed!";
return false;
}
LPVOID LoadLibraryAddress = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
LPVOID Allocate = VirtualAllocEx(Handle, NULL, strlen(Path), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(Handle, Allocate, Path, strlen(Path), NULL);
HANDLE Thread = CreateRemoteThread(Handle, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryAddress, Allocate, 0, NULL);
WaitForSingleObject(Thread, INFINITE); // WAIT FOREVER!
VirtualFreeEx(Handle, Thread, strlen(Path), MEM_RELEASE);
//Start DLL Main Thread
LPVOID MainThreadAddress = (LPVOID)GetProcAddress(GetModuleHandleA("Client.dll"), "MainThread");
Allocate = VirtualAllocEx(Handle, NULL, 0, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(Handle, Allocate, Path, strlen(Path), NULL);
HANDLE MainThread = CreateRemoteThread(Handle, NULL, NULL, (LPTHREAD_START_ROUTINE)MainThreadAddress, Allocate, 0, NULL);
WaitForSingleObject(MainThread, INFINITE); // Wait for Main Thread to start
VirtualFreeEx(Handle, MainThread, strlen(Path), MEM_RELEASE);
CloseHandle(MainThread);
CloseHandle(Thread);
CloseHandle(Handle);
return true;
}
Thanks to anyone who can help.
I don't see any error checking - specifically for the case where you're fetching the address of "MainThread". Is this succeeding?
In order for this to work, you're going to need to explicitly export "MainThread" from your DLL either via a .DEF file or by using __declspec( dllexport ). See this SO link for details.

Readers Writers - Writer thread always stuck with multiple reader thread

New bie here.
I have been working on readers/ writers problem solution.
It works perfectly fine with 1 reader and 1 writer.
But when I modify reader to 2; writer thread always starves. Help me!
It seems Writer thread is stuck somewhere waiting for wrt mutex.
#include <stdio.h>
#include <conio.h>
#include <windows.h>
HANDLE mutex, wrt;
int g_ReadCount = 0;
int g_GlobalData=0;
const int max = 2;
HANDLE reader[max], writer[max];
CRITICAL_SECTION rSect, wSect;
bool bTerminate = true;
DWORD Readers(LPVOID lpdwThreadParam )
{
while(bTerminate)
{
WaitForSingleObject(mutex, INFINITE);
g_ReadCount++;
if(g_ReadCount == 1)
{
WaitForSingleObject(wrt, INFINITE);
}
ReleaseMutex(mutex);
EnterCriticalSection(&wSect);
printf("ThreadId : %d --> Read data : %d ReaderCount %d\n", GetCurrentThreadId(), g_GlobalData, g_ReadCount);
LeaveCriticalSection(&wSect);
WaitForSingleObject(mutex, INFINITE);
g_ReadCount--;
if(g_ReadCount == 0)
{
ReleaseMutex(wrt);
printf("ThreadId : %d Realesed Mutex wrt\n", GetCurrentThreadId());
}
printf("ThreadId : %d ReaderCount %d\n", GetCurrentThreadId(), g_ReadCount);
ReleaseMutex(mutex);
printf("Reader ThreadId : %d Realesed Mutex mutex\n", g_ReadCount);
Sleep(0);
}
return 0;
}
DWORD Writers(LPVOID lpdwThreadParam )
{
int n = GetCurrentThreadId();
int temp = 1;
while(bTerminate)
{
printf("ThreadId : %d Waiting for WRT\n", GetCurrentThreadId());
WaitForSingleObject(wrt, INFINITE);
printf("WRITER ThreadId : %d ***Got WRT\n", GetCurrentThreadId());
++n;
temp++;
if(temp == 100)
{
//bTerminate = false;
}
EnterCriticalSection(&wSect);
printf("Write by ThreadId : %d Data : %d Temp %d\n", GetCurrentThreadId(), n, temp);
g_GlobalData = n;
LeaveCriticalSection(&wSect);
ReleaseMutex(wrt);
}
printf("***VVV***Exiting Writer Thread\n");
return 0;
}
void main()
{
mutex = CreateMutex(NULL, false, "Writer");
wrt = CreateMutex(NULL, false, "wrt");
InitializeCriticalSection(&rSect);
InitializeCriticalSection(&wSect);
DWORD dwThreadId = 0;
for(int i=0; i < max; i++)
{
reader[i] = CreateThread(NULL, //Choose default security
0, //Default stack size
(LPTHREAD_START_ROUTINE)&Readers,
//Routine to execute
(LPVOID) 0, //Thread parameter
0, //Immediately run the thread
&dwThreadId //Thread Id
);
}
for(int i=0; i < 1; i++)
{
writer[i] = CreateThread(NULL, //Choose default security
0, //Default stack size
(LPTHREAD_START_ROUTINE)&Writers,
//Routine to execute
(LPVOID) 0, //Thread parameter
0, //Immediately run the thread
&dwThreadId //Thread Id
);
}
getchar();
}
With more than 1 reader thread, it is quite likely that g_ReadCount will never get to zero, so the wrt mutex will never be released (thus starving the writer). You probably need some kind of indicator that the writer thread is waiting. Then the reader threads would need to give precedence to the writer at some point.
For example, in one implementation I wrote (not saying it is a great way, but it worked) I used a flag that was set/cleared via atomic increment/decrement operations that indicated if a writer thread was waiting for the lock. If so, the readers would hold off. Of course, in that case you also need to then be careful of the opposite situation where writer threads (if more than one) could starve readers. Read/Write locks are tricky.
While working on this problem; I found interesting issue.
During study; we told that Semaphore with max count =1 is equal to Mutex. That is not entirely true.
1) Mutex can not be released by any other thread.
2) Semaphore can be used in such situation.

How can I get which object timed out when using WaitForMultipleObjects?

If I'm using WaitForMultipleObjects, and the function returns WAIT_TIMEOUT, how can I get which object or objects caused the timeout to occur?
Another question I have is if multiple objects are signaled, since the return value only returns the first object that it detects as signaled, how do I get the other objects which are signaled?
#include <windows.h>
#include <stdio.h>
HANDLE ghEvents[2];
DWORD WINAPI ThreadProc( LPVOID );
int main( void )
{
HANDLE hThread;
DWORD i, dwEvent, dwThreadID;
// Create two event objects
for (i = 0; i < 2; i++)
{
ghEvents[i] = CreateEvent(
NULL, // default security attributes
FALSE, // auto-reset event object
FALSE, // initial state is nonsignaled
NULL); // unnamed object
if (ghEvents[i] == NULL)
{
printf("CreateEvent error: %d\n", GetLastError() );
ExitProcess(0);
}
}
// Create a thread
hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID); // receive thread identifier
if( hThread == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return 1;
}
// Wait for the thread to signal one of the event objects
dwEvent = WaitForMultipleObjects(
2, // number of objects in array
ghEvents, // array of objects
FALSE, // wait for any object
5000); // five-second wait
// The return value indicates which event is signaled
switch (dwEvent)
{
// ghEvents[0] was signaled
case WAIT_OBJECT_0 + 0:
// TODO: Perform tasks required by this event
printf("First event was signaled.\n");
break;
// ghEvents[1] was signaled
case WAIT_OBJECT_0 + 1:
// TODO: Perform tasks required by this event
printf("Second event was signaled.\n");
break;
case WAIT_TIMEOUT:
// How can I get which object timed out?
printf("Wait timed out.\n");
break;
// Return value is invalid.
default:
printf("Wait error: %d\n", GetLastError());
ExitProcess(0);
}
// Close event handles
for (i = 0; i < 2; i++)
CloseHandle(ghEvents[i]);
return 0;
}
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
// lpParam not used in this example
UNREFERENCED_PARAMETER( lpParam);
// Set one event to the signaled state
if ( !SetEvent(ghEvents[0]) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return 1;
}
return 0;
}
When the WaitForMultipleObjects(...) returns with the WAIT_TIMEOUT return code, it indicates that none of your you objects you waited for signaled within the given amount of time.
The function essentially sleeps for the time you specify as timeout and only returns earlier, if one of the waitable objects gets signaled before that time. That means that the WAIT_TIMEOUT return code is not associated with any of the objects you wait for.
Your second question is partialy answered by Eregriths comment. To check if other objects are also signaled, you could call WaitForMultipleObjects(...) again, and depending on your needs, set the timeout value to 0 (do not wait). When WaitForMultipleObjects(...) returns with WAIT_TIMEOUT you know that no other objects were in a signaled state at the time of your call, but you should keep in mind, that the object, that caused your first call to return could potentially be signaled again. So you could either exclude it from your array or simply check a single object for its state with the WaitForSingleObject(...) function.
If you want to make sure all objects are signaled, you can also play with the bWaitAll parameter. WaitForMultipleObjects(...) will then only return if all your objects are in a signaled state.,
Hope that helps a bit.