re-block a thread

Hello!
I study, what is the best practice
for reblocking a thread.

If I use a Mutex,
the thread waits for release of the mutex.

Short after the thread should block again
and wait for the similar event
triggered by the main thread.

The main thread should not be blocked,
waiting on the same mutex.

Thank you for some tips

Erhy
That sounds like a recipie for dead-lock.

You wait with WaitForSingleObject/WaitForMultipleObjects.
Last edited on
Alternated usage of mutex
is my idea:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// TestMutex.cpp for re-lock a thread

// ... some code

HANDLE hThr0Mutexs[2]; // 2 mutex which take in turn to lock the threa
volatile int IxThr0M = 0;	// index of activ mutex

HANDLE hThreadWhichShouldBeBlocked = NULL; 

void MyDebugOut(TCHAR *text, int v) //should be smarter
{
	SYSTEMTIME st;
	TCHAR buf[256];

	GetLocalTime(&st);
	swprintf(buf, (sizeof(buf) / sizeof(buf[0])) - 1, _T("%02d:%02d:%02d|%03d %s %d\n"),
		st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, text, v);
	OutputDebugString(buf);
}

DWORD WINAPI functionForThreads(LPVOID lParam)
{
	int z = 1;
	do
	{
		MyDebugOut(_T("Thread waits for Mutex"), IxThr0M);
		WaitForSingleObject( hThr0Mutexs[IxThr0M], INFINITE);
		MyDebugOut(_T("Thread released from Mutex"), IxThr0M );
		ReleaseMutex(hThr0Mutexs[IxThr0M]);
		IxThr0M ^= 1; //XOR index of the mutex
		//
		// here some short code for the tasks of the thread
		// 
	} while (z);
	return 0;
}


int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{

// ... some code

{
	int i;
	for (i = 0; i < 2; i++) //create both mutex
	{
		hThr0Mutexs[i] = CreateMutex(	// to stop thread while starting
			NULL,                   // default security attributes
			0,			// not owned
			NULL);
	}
}

// ... some code

	{
		DWORD resWait;
		/* mutex have an internal block counter,
		so its important the number of locks are equal the number of releases
		belonging one thread*/

		// to block thread on start
		resWait = WaitForSingleObject(hThr0Mutexs[(IxThr0M)], INFINITE); // should not wait
		MyDebugOut(_T("Initial block thread on start result="), resWait);

		// only once to create a thread
		hThreadWhichShouldBeBlocked = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&functionForThreads, NULL, 0, 0);
 		int w = 1;
		do
		{
			Sleep(9000); //simul wait for action
			// tasks to do for the thread
			MyDebugOut( _T("to block thread after the next loop with Mutex"), IxThr0M ^ 1);

			// to block thread on next loop
			resWait = WaitForSingleObject(hThr0Mutexs[(IxThr0M ^ 1)], INFINITE); // should not wait
			MyDebugOut(_T("after blocking WaitForSingleObject result="), resWait);

			ReleaseMutex(hThr0Mutexs[IxThr0M]); // for starting thread loop

			// wait for next action in the begin of the loop
		} while (w);
		break;
	}
Last edited on
sorry I',m newbie,
it is very simple with events to solve this problem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// TestEvent.cpp

#include "stdafx.h"
#include "TestEvent.h"

// Global
HANDLE hEventHandle = NULL;
HANDLE hThreadHandle = NULL;

void MyDebugOut(TCHAR *text, int v) //should be smarter
{
	SYSTEMTIME st;
	TCHAR buf[256];

	GetLocalTime(&st);
	swprintf(buf, (sizeof(buf) / sizeof(buf[0])) - 1, _T("%02d:%02d:%02d|%03d %s %d\n"),
		st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, text, v);
	OutputDebugString(buf);
}

DWORD WINAPI ThreadActionFunction(LPVOID lParam)
{
	int i = 0;
	int z = 1;
	DWORD resWait;
	
	do
	{
		i++;
		MyDebugOut(_T("Thread: wait for event i="), i);
		resWait = WaitForSingleObject(hEventHandle, INFINITE);

		MyDebugOut(_T("Thread: run because an event, resWait="), resWait);


		if ( !ResetEvent(hEventHandle) ) //release for next turn
		{
			MyDebugOut( _T("Thread: ResetEvent failure(7)! i=") , i );
			exit(-1);
		}

		/* some thread acton*/
		Sleep(100);

	} while (z);
	MyDebugOut(_T("Thread: loop exited on i="), i);
	return -1;
}


int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPTSTR    lpCmdLine,
	_In_ int       nCmdShow)
{

	hEventHandle = CreateEvent(	// to stop thread while starting
		NULL,                       // default security attributes
		false,						// auto reset mode
		false,						// not signaled
		NULL);

	if ( !hEventHandle ) 
	{
		MyDebugOut(_T("main: CreateEvent failure! "), -1);
		exit(-1);
	}

	MyDebugOut(_T("main: Initial block of thread on start"), 0);

	hThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadActionFunction, NULL, 0, 0);

	// action loop

	int j = 0;
	int w = 1;
	do
	{
		j++;
		Sleep(1000); //simul action

		MyDebugOut(_T("main: will release thread j="), j);
		// ReleaseMutex(hEventHandle_IxThr0M]); // thread should virtuel release shift key
		if ( !SetEvent(hEventHandle) ) //release if shift key with hand
		{
			MyDebugOut(_T("main: SetEvent failure(2)! j="), j);
			exit(-1);
		}
	} while (w);
	MyDebugOut(_T("main: exit loop on j="), j);
	return 0;
}

Last edited on
Topic archived. No new replies allowed.