您的位置:首页 > 编程语言 > C语言/C++

C++线程同步总结

2015-08-27 09:29 417 查看
/*know it before
//unsigned long _beginthreadex( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr );
//第1个参数:安全属性,NULL为默认安全属性
//第2个参数:指定线程堆栈的大小。如果为0,则线程堆栈大小和创建它的线程的相同。一般用0
//第3个参数:指定线程函数的地址,也就是线程调用执行的函数地址(用函数名称即可,函数名称就表示地址)
//第4个参数:传递给线程的参数的指针,可以通过传入对象的指针,在线程函数中再转化为对应类的指针
//第5个参数:线程初始状态,0:立即运行;CREATE_SUSPEND:suspended(悬挂)
//第6个参数:用于记录线程ID的地址
//如果你的编程只调用 Win32 API/SDK ,就放心用 CreateThread;如果要用到
//C++ 运行时间库,那么就要使用 _beginthreadex ,并且需要在编译环境中选择 Use MultiThread Lib/DLL
//绝对不要调用系统自带的CreateThread函数创建新的线程,而应该使用_beginthreadex,除非你在线程中绝不使用需要tiddata结构的运行时库函数

//WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
//threadNum 句柄的数量 最大值为MAXIMUM_WAIT_OBJECTS(64)
//hThread 句柄数组的指针 HANDLE 类型可以为(Event,Mutex,Process,Thread,Semaphore )数组
//BOOL bWaitAll 等待的类型,如果为TRUE 则等待所有信号量有效在往下执行,FALSE 当有其中一个信号量有效时就向下执行
//DWORD dwMilliseconds 超时时间 超时后向执行。 如果为WSA_INFINITE 永不超时。如果没有信号量就会在这死等。

//CloseHandle(hThread[i]);
//只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了,放弃控制权。并没有结束线程。
*/

//用Interlocked系列函数实现线程同步实例如下:
//旋转锁 当然这种方法会浪费cpu时间,因为cpu要不断地执行InterlockedExchange()函数,单CPU不推荐这种方法。
#include <iostream>
using namespace std;
#include <process.h>
#include <windows.h>
const int threadNum=10;
HANDLE hThread[threadNum];
volatile unsigned int ISOK=0;
unsigned int _stdcall Interlocked(PVOID threadId)
{
while(InterlockedExchange(&ISOK,1)==1) ;
cout<<"线程:"<<*(int*)threadId<<"开始"<<endl;
Sleep(100);
cout<<"线程:"<<*(int*)threadId<<"结束"<<endl;
InterlockedExchange(&ISOK,0);
return 0;
}

void InterlockedTest()
{
int threadId[threadNum];
for(int i=0;i<threadNum;i++)
{
threadId[i]=i+1;
}
cout<<"1:用Interlocked系列函数实现线程同步"<<endl;
for(int i=0;i<threadNum;i++){
hThread[i]=(HANDLE)_beginthreadex(NULL, 0, Interlocked,threadId+i, 0, NULL);
}
WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
for(int i=0;i<threadNum;i++)
{
CloseHandle(hThread[i]);
}
}

//用CRITICAL_SECTION及其系列函数实现线程同步实例如下:
//关键段
// #include <iostream>
// using namespace std;
// #include <process.h>
// #include <windows.h>
// const int threadNum=10;
// HANDLE hThread[threadNum];
CRITICAL_SECTION g_cs;//构造一个CRITICAL_SECTION实例
unsigned int _stdcall  CriticalSection(PVOID threadId)
{
EnterCriticalSection(&g_cs);//进入关键段
cout<<"线程:"<<*(int*)threadId<<"开始"<<endl;
Sleep(100);
cout<<"线程:"<<*(int*)threadId<<"结束"<<endl;
LeaveCriticalSection(&g_cs);//进入关键段
return 0;
}

void CriticalSectionTest()
{
int threadId[threadNum];
for(int i=0;i<threadNum;i++)
{
threadId[i]=i+1;
}
InitializeCriticalSection(&g_cs);//初始化g_cs的成员
cout<<"2:用CRITICAL_SECTION及其系列函数实现线程同步"<<endl;
for(int i=0;i<10;i++){
hThread[i]=(HANDLE)_beginthreadex(NULL, 0, CriticalSection,threadId+i, 0, NULL);
}
WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
for(int i=0;i<threadNum;i++)
{
CloseHandle(hThread[i]);
}
DeleteCriticalSection(&g_cs);//删除关键段
}

/*
SRWLock的目的和关键段是一样的,就是对资源的保护,不让其他线程访问。
不同的是,它区分线程是读线程还是写线程。
我们都是知道,一个资源可以同时被多个线程同时读,就是不能同时读,或是读写。
也是是说写必须是独占的方式,而读可以以共享的方式访问,如果以共享的方式访问肯定就比CRITICAL_SECTION性能好。
*/
//用RTL_SRWLOCK及其系列函数实现线程同步实例如下:
//读写锁
RTL_SRWLOCK  lock;//构造一个RTL_SRWLOCK实例
unsigned int _stdcall  SrwLock(PVOID threadId)
{
AcquireSRWLockExclusive(&lock);//进入读写锁
cout<<"线程:"<<*(int*)threadId<<"开始"<<endl;
Sleep(100);
cout<<"线程:"<<*(int*)threadId<<"结束"<<endl;
ReleaseSRWLockExclusive(&lock);//进入读写锁
return 0;
}

void SrwLockTest()
{
int threadId[threadNum];
for(int i=0;i<threadNum;i++)
{
threadId[i]=i+1;
}
InitializeSRWLock(&lock);//初始化lock的成员
cout<<"3:用RTL_SRWLOCK及其系列函数实现线程同步"<<endl;
for(int i=0;i<10;i++){
hThread[i]=(HANDLE)_beginthreadex(NULL, 0, SrwLock,threadId+i, 0, NULL);
}
WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
for(int i=0;i<threadNum;i++)
{
CloseHandle(hThread[i]);
}

}
//用事件内核对象实现线程同步实例如下:
//事件
HANDLE event1;

unsigned int _stdcall  Event(PVOID threadId)
{
WaitForSingleObject(event1,INFINITE);
int* p=(int*)threadId;
cout<<"线程:"<<*p<<"开始"<<endl;
Sleep(100);
cout<<"线程:"<<*p<<"结束"<<endl;
SetEvent(event1);
return 1;
}

void EventTest()
{
int threadId[threadNum];
for(int i=0;i<threadNum;i++)
{
threadId[i]=i+1;
}
event1=CreateEvent(NULL,false,true,NULL);
cout<<"4:用事件内核对象实现线程同步"<<endl;
for(int i=0;i<threadNum;i++)
{
hThread[i] =(HANDLE)_beginthreadex(NULL, 0, Event ,threadId+i, 0, NULL);
}
WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
for(int i=0;i<threadNum;i++)
{
CloseHandle(hThread[i]);
}
CloseHandle(event1);
}

//用信号量内核对象实现线程同步实例如下:
//信号量
HANDLE semaphore;
unsigned int _stdcall  Semaphore(PVOID threadId)
{
WaitForSingleObject(semaphore, INFINITE);
cout<<"线程:"<<*(int*)threadId<<"开始"<<endl;
Sleep(100);
cout<<"线程:"<<*(int*)threadId<<"结束"<<endl;
ReleaseSemaphore(semaphore,1,NULL);
return 0;
}

void SemaphoreTest()
{
int threadId[threadNum];
for(int i=0;i<threadNum;i++)
{
threadId[i]=i+1;
}
semaphore=CreateSemaphore(NULL,1,1,NULL);
cout<<"5:用信号量内核对象实现线程同步"<<endl;
for(int i=0;i<10;i++){
hThread[i]=(HANDLE)_beginthreadex(NULL, 0, Semaphore,threadId+i, 0, NULL);
}
WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
for(int i=0;i<threadNum;i++)
{
CloseHandle(hThread[i]);
}
CloseHandle(semaphore);
}
void main()
{
InterlockedTest();
CriticalSectionTest();
SrwLockTest();
EventTest();
SemaphoreTest();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: