现在的位置: 首页 > 综合 > 正文

临界区例子及相关函数翻译

2018年02月15日 ⁄ 综合 ⁄ 共 1566字 ⁄ 字号 评论关闭

例子:记录线程调用顺序

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

#define THREADCOUNT 9

CRITICAL_SECTION  testCS;
DWORD WINAPI ThreadFunc( LPVOID );
std::vector<int> orderVec;

//记录线程调用顺序
int main( void )
{
	HANDLE aThread[THREADCOUNT];
	DWORD ThreadID;
	int i;
	InitializeCriticalSection(&testCS);
	// Create worker threads

	for( i=0; i < THREADCOUNT; i++ )
	{
		aThread[i] = CreateThread( 
			NULL,       // default security attributes
			0,          // default stack size
			ThreadFunc, //(LPTHREAD_START_ROUTINE) 
			(LPVOID)i,       // no thread function arguments
			0,          // default creation flags
			&ThreadID); // receive thread identifier
	}

	Sleep(100);
	for( i=0; i < THREADCOUNT; i++ )
		CloseHandle(aThread[i]);
	
	int count = orderVec.size();
	cout << " order of calling thread:";
	for (int i=0; i<count; ++i)
	{
		cout << orderVec[i] << ", ";
	}
	DeleteCriticalSection(&testCS);
	system("pause");
	return 0;
}


DWORD WINAPI ThreadFunc( LPVOID lpParam )
{ 
	//如果不加临界区 vector.push_back操作可能中途被打断 出现错误
	EnterCriticalSection(&testCS);
	int i = (int)lpParam;
	orderVec.push_back(i);
	LeaveCriticalSection(&testCS);
	return TRUE; 
}

结果:

 order of calling thread:0, 1, 2, 4, 5, 3, 7, 6, 8, 请按任意键继续. . .

InitializeCriticalSection function

初始化一个临界区对象

void WINAPI InitializeCriticalSection(

  _Out_  LPCRITICAL_SECTION lpCriticalSection

);

参数

lpCriticalSection [out]

指向临界区对象的指针

注意

        单进程中的线程可以使用临界界对象来解决青互斥同步问题。但不保证线程得到临界区对象的顺序,系统公平对待每个线程。进程负责为临界区对象分配内存。即定义一个类型为CRITICAL_SECTION变量。在使用临界区对象之前,进程中的线程必须初始化临界区对象。在临界区对象初始化之后,线程可以使用函数EnterCritical TryEnterCriticalSectionLeaveCriticalSection函数来互斥地访问共享资源。在不同进程中的线程同步,可以使用mutex对象。

   临界区对象不能被移动,也不能被复制。进程不能修改临界区对象,但这是不符合逻辑的。只能使用临界区函数管理临界区对象。当你想结束一个临界区对象时,调用DeleteCriticalSection函数。

    在重新初始化临界区对象之前,临界区对象必须被删除。初始化一个已经初始化的临界区对象,结果是未知的。

【上篇】
【下篇】

抱歉!评论已关闭.