basic multi-threading

Hello, beginner to C++ and code in general here.

I have been teaching myself how to code for about the last month (using on-line tutorials), and am in the process of creating a simple text-based RPG using Microsoft Visual Studio 2010.

Things have been going good and my understanding of classes and pointers is growing, but I have run into a road-block.

I am wanting to create two combat loops for my RPG for two different classes (the attacker and the attacked) that will execute simultaneously. I understand that multi-threading is the key, and am trying to get a better understanding of it, but the MSDN website has left me with a very foggy understanding of multi-threading.

Which brings me to my problem.

From looking at the MSDN website and their pages on multi-threading, i created a basic program that will set two different threads to increase a global integer and then use std::cout to print it to the console.

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
// multi-threading_practice.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>
#include <iostream>
#include <string>

//The function getrandom returns a random number between
//min and max, which must be in integer range.
#define getrandom(min,max)(SHORT)((rand()%(int)(((max)+1)-\(min)))+(min))

using namespace std;

HANDLE hRunMutex;			//"Keep Running" mutex
HANDLE hPrintMutex;			//"Integer printed" mutex
int ThreadNr;				//number of threads started
int x;

void printNumber(void* pInt)
{
	int i=(int)pInt;
	while(i<100)
	{
		WaitForSingleObject(hPrintMutex,INFINITE);
		++i;
		cout<<i<<endl;
		ReleaseMutex(hPrintMutex);
	}
}

void printNumberDouble(void* pInt)
{
	int i=(int)pInt;
	while(i<100)
	{
		WaitForSingleObject(hPrintMutex,INFINITE);
		++i;
		++i;
		cout<<i<<endl;
		ReleaseMutex(hPrintMutex);
	}
}

int main()
{
	x=0;
	
	_beginthread(printNumber,0,&x);
	_beginthread(printNumberDouble,0,&x);
	return 0;
}


The above code will compile fine, but when ran, a console is created, and all that is printed is the "press any key to continue" after the main() function executes.

From my understanding, this should have worked, but then my understanding of multi-threading is very, very foggy.

Any clarification would be very much appreciated.
Where are you creating your mutex?

Also, your main function is creating the threads and then immediately exiting, which will cause the app to exit (when you return from main, the app shutdown sequence is run).

You need to wait for your threads in main().
Last edited on
Your two print functions are being passed an void* pointer, which you are then casting directly to an int. It's very likely that the address of x is > 100, so your loop won't execute at all.

Also, you're incrementing a local int, not the global, in each function.

Jim
AHH, i wasnt creating my mutex.

......okay, I added this to my main function:

hPrintMutex=CreateMutex(NULL,false,NULL);

so the main function now looks like this:
1
2
3
4
5
6
7
8
9
int main()
{
	x=0;
	hPrintMutex=CreateMutex(NULL,false,NULL);
	
	_beginthread(printNumber,0,&x);
	_beginthread(printNumberDouble,0,&x);
	return 0;
}


still getting same problem, no output.

like i said before, i have an extremely foggy understanding of multi-threading.

edit:

also changed the printNumber() and printNumberDouble() functions to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void printNumber(void* pInt)
{
	while(*x<100)
	{
		WaitForSingleObject(hPrintMutex,INFINITE);
		++*x;
		cout<<*x<<endl;
		ReleaseMutex(hPrintMutex);
	}
}

void printNumberDouble(void* pInt)
{
	while(*x<100)
	{
		WaitForSingleObject(hPrintMutex,INFINITE);
		++*x;
		++*x;
		cout<<*x<<endl;
		ReleaseMutex(hPrintMutex);
	}
}


i dont have much experience with de-referencing pointers, but i believe i did it correctly.

still, after the change, no dice. (not working).
Last edited on
okay, changed main() again.

this time, including a wait for the other two threads before exiting:
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
	x=0;
	hPrintMutex=CreateMutex(NULL,false,NULL);
	
	HANDLE hThread1=(HANDLE)_beginthread(printNumber,0,&x);
	HANDLE hThread2=(HANDLE)_beginthread(printNumberDouble,0,&x);

	WaitForSingleObject(hThread1,INFINITE);
	WaitForSingleObject(hThread2,INFINITE);
	return 0;
}


I must be a little bit closer to the desired outcome, because this time, the program crashed when ran.

At least its not simply giving me no output at all, but i believe that there is still something that I'm missing.

This is what happens when i try to learn multi-threading by using a Google-search. nearly every result gave me a different, incomplete example of multi-threading.

Would buying a college textbook help? (im a 5th year business student, so getting my hands on a college code book wouldnt be hard)
Instead of waiting for thread 1, then after it ends waiting for thread 2, should you not use WaitForMultipleObjects?
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx

Also, multithreading is a really bad way to go about solving this problem. You should think of things in a frame-by-frame perspective, and give each moving object on screen one 'tick' per frame to move one way. This can be done in a while loop calling each object's tick function with an OOP setup; multithreading is far too complicated for such a simple matter.
You're now mistakenly using int x as a pointer and dereferencing it within your thread functions.

If you want to use the thread parameter, cast the void* to an int* and use that within the function.
1
2
3
4
5
6
7
int* xp = (int*)pInt;
while (*xp < 100)
{
  // mutex
  ++*xp;
  // mutex
}


Alternately, just use x directly - no need for pointers.

1
2
3
4
5
6
while (x < 100)
{
  // mutex
  ++x;
  // mutex
}


Jim
Last edited on
Jim, you are a genius.

your example of int pointers in your above post:
1
2
3
4
5
6
7
int* xp = (int*)pInt;
while (*xp < 100)
{
  // mutex
  ++*xp;
  // mutex
}

was what i was missing.

still having a slight problem, however.

only hThread1 is executing. im not getting any ouput increments of 2.

edit:
fixed. added Sleep(10) at the end of each printNumber function, and now am getting the intended output.

time to move on to more advanced multi-threading.

I'll probably be back on this forum at some point in time with more questions.

just for anyone that may need to see the end code, i am going to post it at the end of this reply:
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
// multi-threading_practice.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>
#include <iostream>
#include <string>

using namespace std;


HANDLE hPrintMutex;			//"Integer printed" mutex
int ThreadNr;				//number of threads started
int x;

void printNumber(void* pInt)
{
	int* xp=(int*)pInt;
	while(*xp<100)
	{
		WaitForSingleObject(hPrintMutex,INFINITE);
		++*xp;
		cout<<*xp<<endl;
		ReleaseMutex(hPrintMutex);
		Sleep(10);
	}
}

void printNumberDouble(void* pInt)
{
	int* xp=(int*)pInt;
	while(*xp<99)
	{
		WaitForSingleObject(hPrintMutex,INFINITE);
		*xp+=2;
		cout<<*xp<<endl;
		ReleaseMutex(hPrintMutex);
		Sleep(10);
	}
}

int main()
{
	x=0;
	hPrintMutex=CreateMutex(NULL,false,NULL);
	
	HANDLE hThread1=(HANDLE)_beginthread(printNumber,0,&x);
	HANDLE hThread2=(HANDLE)_beginthread(printNumberDouble,0,&x);

	WaitForSingleObject(hThread1,INFINITE);
	WaitForSingleObject(hThread2,INFINITE);
	return 0;
}


hope this helps anyone who is google-searching multi-threading like i did.
Last edited on
Topic archived. No new replies allowed.