多线程编程(三)

_beginthreadex 也能够创建线程

包含头文件process.h
函数原型
unsigned long _beginthreadex(
void *security,                  //指向 SECURITY_ATTRIBUTES 结构的指针
unsigned stack_size,        //新线程的堆栈大小或 0
unsigned ( __stdcall *start_address )( void * ),   //开始执行新线程的例程的起始地址
void *arglist,    //要传递到新线程的参数或 NULL。
unsigned initflag,  //控制新线程的初始状态的标志。 将 initflag 设置为 0 以立即运行
unsigned *thrdaddr             //指向接收线程标识符的 32 位变量。 如果此变量为 NULL,则不可用。

);

CreateThread与_beginthreadex区别

下面是一些一般性的规则。如果主线程以外的任何线程进行以下操作,你就应该使用多线程版的 C runtime library ,并使用_beginthreadex()  和 _endthreadex():  

  • 在C 程序中使用 malloc()  和 free() ,或是在 C++  程序中使用 new  和 delete 。 
  • 调用 stdio.h  或 io.h  中声明的任何函数,包括像 fopen() 、open() 、
  • getchar() 、write() 、printf() 等等。所有这些函数都用到共享的数据结构以及errno。你可以使用 wsprintf()  将字符串格式化,如此就不需要 stdio.h  了。如果链接器抱怨说它找不到 wsprintf() ,你得链接 USER32.LIB 。 
  • 使用浮点变量或浮点运算函数。 
  • 调用任何一个使用了静态缓冲区的 runtime函数,如asctime() 、strtok() 或 rand() 。

一个程序如果使用多个线程,而不在任何 worker 线程中调用runtime  library ,能够与单线程版的 runtime  library  链接并以 CreateThread() 取代 _beginthreadex() 。

#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;

unsigned __stdcall ThreadProc(void* lpParameter)
{
	cout<<"GetCurrentThreadId()="<<GetCurrentThreadId()<<endl;
	int n = (int)lpParameter;
	while (n--)
	{
		cout<<"this is a test"<<endl;
		Sleep(1000);
	}

	return 100;
}

int main()
{

	unsigned threadId;
	HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, (void*)5, 0, &threadId);
	if (hThread == NULL)
	{
		cout<<"error with code"<<GetLastError()<<endl;
		exit(1);
	}

	cout<<"threadId="<<threadId<<endl;

	DWORD ret;
	ret = WaitForSingleObject(hThread, INFINITE);
	if (ret == WAIT_FAILED)
	{
		cout<<"error with code="<<GetLastError()<<endl;
		exit(1);
	}
	else if (ret == WAIT_OBJECT_0)
	{
		cout<<"wait succ"<<endl;
	}

	//Sleep(10*1000);

	CloseHandle(hThread);
	return 0;
}

线程的封装

#ifndef _JTHREAD_H_
#define _JTHREAD_H_

#include <Windows.h>

class JThread
{
public:
	JThread();
	virtual ~JThread();

	virtual void Run() = 0;    //运行函数为纯虚函数

	static unsigned __stdcall ThreadFun(void* p);  //线程函数
	bool Start();   //启动

	void Wait(DWORD timeout = INFINITE);  //阻塞

private:
	HANDLE hThread_;
	unsigned threadId_;
};

#endif // _JTHREAD_H_


#include "JThread.h"
#include <process.h>

JThread::JThread() : hThread_(NULL), threadId_(0)
{
}

JThread::~JThread()
{
	if (hThread_ != NULL)
		CloseHandle(hThread_);
}

unsigned __stdcall JThread::ThreadFun(void* p)
{
	JThread* jtp = (JThread*)p;    //基类指针指向派生类
	jtp->Run();                   //动态绑定
	return 0;
}

bool JThread::Start()
{
	hThread_ = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, this, 0, &threadId_);  //this作为ThreadFun的参数
	return hThread_ != NULL;
}

void JThread::Wait(DWORD timeout)
{
	
	WaitForSingleObject(hThread_, timeout);
}

#include "JThread.h"
#include <iostream>
using namespace std;

class TestThread : public JThread
{
public:
	TestThread(int n) : n_(n)
	{

	}
	~TestThread()
	{

	}

	void Run()        //覆盖Run函数
	{
		while (n_--)
		{
			cout << "this is a test" << endl;
			Sleep(1000);
		}
	}

private:
	int n_;
};

int main()
{
	TestThread t(5);
	t.Start();
	t.Wait();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/alatebloomer/article/details/80695491