Win32API下的多线程编程入门


多线程,Multi-Thread。移步别处理解Thread和Process。多线程可用多种API实现,这里用Win32 API实现最简单的多线程,线程彼此独立,不涉及线程间的数据共享。

先直接上程序:

#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <string>
#include <iostream>

class ThreadX
{
private:
	std::string threadName;
	int loopStart;
	int loopEnd;
	int loopStep;
public:
	ThreadX(int x, int y, int z) : loopStart(x), loopEnd(y), loopStep(z) { }
	void SetThreadName(std::string name)
	{
		threadName = name;
	}
	static unsigned __stdcall ThreadEntryPoint(void* pThis)
	{
		ThreadX* pTh = (ThreadX*)pThis;
		pTh->StartUp();

		return 1;
	}
	void StartUp()
	{
		for (int i = loopStart; i < loopEnd; ++i)
		{
			if (i % loopStep == 0)
			{
				//std::cout << threadName << ": " << i << std::endl;
				printf("%s : %d \n", threadName.c_str(), i);
			}
		}
		printf("%s terminating...\n", threadName.c_str());
	}
};

int main()
{
	ThreadX* obj1 = new ThreadX(0, 1000000, 20000);
	obj1->SetThreadName("Thread1");
	HANDLE hThread1;
	unsigned thread1Id;
	hThread1 = (HANDLE)_beginthreadex(NULL,
		0,
		ThreadX::ThreadEntryPoint,
		obj1,
		CREATE_SUSPENDED,
		&thread1Id);
	if (hThread1 == NULL)
	{
		printf("Failed to create Thread 1. \n");
	}
	DWORD dwExitCode;
	GetExitCodeThread(hThread1, &dwExitCode);
	printf("initial thread 1 exit code = %d \n", dwExitCode);

	ThreadX* obj2 = new ThreadX(-1000000, 0, 20000);
	obj2->SetThreadName("Thread2");
	HANDLE hThread2;
	unsigned thread2Id;
	hThread2 = (HANDLE)_beginthreadex(NULL,
		0,
		ThreadX::ThreadEntryPoint,
		obj2,
		CREATE_SUSPENDED,
		&thread2Id);
	if (hThread2 == NULL)
	{
		printf("Failed to create Thread 1. \n");
	}
	GetExitCodeThread(hThread1, &dwExitCode);
	printf("initial thread 2 exit code = %d \n", dwExitCode);

	ResumeThread(hThread1);
	ResumeThread(hThread2);

	WaitForSingleObject(hThread1, INFINITE);
	WaitForSingleObject(hThread2, INFINITE);

	GetExitCodeThread(hThread1, &dwExitCode);
	printf("thread 1 exit with code : %d \n", dwExitCode);

	GetExitCodeThread(hThread2, &dwExitCode);
	printf("thread 2 exit with code : %d \n", dwExitCode);

	CloseHandle(hThread1);
	CloseHandle(hThread2);

	delete(obj1);
	obj1 = NULL;
	delete(obj2);
	obj2 = NULL;

	system("pause");
	return 0;
}

运行结果如下:

记录以下几点。

1. 

hThread1 = (HANDLE)_beginthreadex(NULL,
0,
ThreadX::ThreadEntryPoint,
obj1,
CREATE_SUSPENDED,
&thread1Id);

ResumeThread(hThread1);

WaitForSingleObject(hThread1, INFINITE);

GetExitCodeThread(hThread1, &dwExitCode);

CloseHandle(hThread1);

这个Sample里用到的关于多线程的Win32 API就上面的几个粗体标示的函数。

注意:

(1)用_beginthreadex 而非CreateThread,因为CreateThread用于CRT时会导致内存泄露。

官方说明如下:http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx

A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and_endthreadex functions for thread management rather than CreateThread and ExitThread; this requires the use of the multithreaded version of the CRT. If a thread created using CreateThread calls the CRT, the CRT may terminate the process in low-memory conditions.” 

(2) _beginthreadex 创建的进程被Suspend了,所以才需要后面的ResumeThread(hThread1) 将进程唤醒。

(3)当线程还存活时,GetExitCodeThread返回的是259,当线程运行结束时,返回的是1.


2. 

输出信息时,推荐用printf,不容易被其他进行插断。用cout时,stream容易在不同Thread中跳转。 如果将StartUp()函数里的信息输入用注释的那行代替printf那行,运行结果容易出现这种问题:




3.

为了显示出多线程的同时运行,即最终的运行结果里Thread1和Thread2的信息穿插输出,需要保证StartUp()里循环的次数够多才输出信息,否则其他Thread来不及插队打印信息。

比如,将

ThreadX* obj1 = new ThreadX(0, 1000000, 20000);

ThreadX* obj2 = new ThreadX(-1000000, 0, 20000);

改为

ThreadX* obj1 = new ThreadX(10, 600, 7);

ThreadX* obj2 = new ThreadX(10001, 10900, 9);

运行结果就变为:


即看起来像是一个线程运行结束后才开始另一个线程。 不是我们想看到的效果-_-


最后,推荐一个多线程入门的教程:http://www.codeproject.com/Articles/14746/Multithreading-Tutorial  ,讲解和例子都很棒,尤其是前面4个例子。



  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值