First Attempt at Multithreading

This is my first attempt at multithreading, based on some code from MSDN.

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
#include <iostream>
using namespace std;
#include <windows.h> //"For all things Windows, include windows.h!"

volatile bool Locked = false;

unsigned long Thread0(int* val)
{
	while(Locked)
	{
		Sleep(0);
	}
	Locked = true;
	cout << "The number of the day is: " << *val << endl;
	Locked = false;
	Sleep(0);
	while(Locked)
	{
		Sleep(0);
	}
	Locked = true;
	cout << "The number of the morning is: " << unsigned long(val) << endl;
	Locked = false;
	return(0);
}

unsigned long Thread1(int* val)
{
	while(Locked)
	{
		Sleep(0);
	}
	Locked = true;
	cout << "The number of the night is: " << *val << endl;
	Locked = false;
	return(0);
}

int main()
{
	int temp0 = 7;
	int temp1 = 14;

	HANDLE hThread0 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&Thread0, &temp0, 0, NULL);
	HANDLE hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&Thread1, &temp1, 0, NULL);
	if (hThread0 == NULL || hThread1 == NULL)
	{
		if (hThread0 != NULL){ CloseHandle(hThread0); }
		if (hThread1 != NULL){ CloseHandle(hThread1); }
		cerr << "Failed to make a thread." << endl;
		cin.sync();
		cin.ignore();
		return 1;
	}

	WaitForSingleObject(hThread0, 1000);
	CloseHandle(hThread0);
	WaitForSingleObject(hThread1, 1000);
	CloseHandle(hThread1);

	cin.sync();
	cin.ignore();
}


I feel more confident with multithreading now and how it works, and I have found that 10% of the time Thread1 gets the lock before Thread0, so I can figure out what to do with all this stuff.

I'm wondering if you guys have any pointers tips for me, or if you want to recommend one practice over another, etc. As this it my first time doing any of this stuff, and I want to make the right habits first :)
closed account (S6k9GNh0)
1. C++0x is including a cross-platform thread facility named std::thread. Although, since C++0x is not yet final (I don't think), use of Boost.Thread is often recommended (which is quite similar if not the same as std::thread to the point that you can simply change namespaces). Even if you are not coding for Linux or any other platform, the facilities provided are often easier to use than whatever API is given from the OS (pthreads, Win32 threads).

2. Use mutexes instead of boolean-based locks. Mutex facilities are provided with std::thread or Boost.Thread.
Last edited on
There's nothing wrong with the Win32 CreateThread() function. You just need to conciously try not to create race conditions in your code. Windows also has these things called mutex's but in most cases good planning means you won't need to use those either.

A few tips I have:

- Break your program flow up so that each thread works on it's own independent task. Like one thread for music, another one for rendering, another one for watching for input etc. This makes mutex locks and the like irrelevent. In your example it doesn't matter because the task is simplistic, this is more for when you actually go to use them.

- Always remember that threads kick off asyncronously, that means thread number four doesn't care if thread zero started yet. This is important if you are expecting them to return data in a certain order you need to have them return data that doesn't need to be sorted or have some way for them to index the data. Even something like the ostream will get garbeled up if you don't plan it right

- Read this article if you get some down time: http://blogs.technet.com/b/markrussinovich/archive/2009/07/08/3261309.aspx

- Don't ignore the fifth argument to "CreateThread()", sometimes you may want to load a thread into memory but not kick it off until another even has occured.

That's about it off the top of my head. If I think of any more I'll come back here.
Topic archived. No new replies allowed.