Windows下的线程同步

  总结一下Windows下的线程同步方法。


首先是WaitForSingleObject函数,每个方法都用到了。

DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD dwMilliseconds
);

参数
hHandle      等待对象的 handle (代表一个核心对象)。在本例中,此为线程 handle 。
dwMilliseconds   等待的最长时间。时间终了,即使 handle 尚未成为激发状态,此函数还是要返回。此值可以是 0
        (代表立刻返回),也可以是 INFINITE 代表无穷等待。

1、信号量

HANDLE CreateSemaphore(
  LPSECURITY_ATTRIBUTES lpAttributes,
  LONG lInitialCount,
  LONG lMaximumCount,
  LPCTSTR lpName
);

参数
lpAttributes       安全属性。如果是 NULL 就表示要使用默认属性。Windows 95 忽略这一参数。
lInitialCount      sem aphore 的初值。必须大于或等于 0,并且小于或等于 lMaxim umCount。
lMaximumCount    Sem aphore 的最大值 。 这也就是在同一时间内能够锁住 sem aphore 之线程的最多个数。
lpName        Sem aphore 的名称(一个字符串)。任何线程(或进程) 都可以根据这一名称引用 到这个       semaphore。这个值可以是 NULL ,意思是产生一 个没有名字的 sem aphore。

BOOL ReleaseSemaphore(
    HANDLE hSemaphore,
    LONG lReleaseCount,
    LPLONG lpPreviousCount
);

参数
hSemaphore     Sem aphore 的 handle 。
lReleaseCount     Sem aphore 现值的增额。该值不可以是负值或 0。
lpPreviousCount     藉此传回 sem aphore 原来的现值。

#include <iostream>
#include <time.h>
#include <string>
#include <Windows.h>

using namespace std;

HANDLE msg;
string goods;

void delay()
{
	int k1 = rand()%30000+1;

	while (k1)
	{
		int k2 = rand()%30000+1;;
		while(k2)
		{
			k2--;
		}
		k1--;
	}
}

DWORD WINAPI func1(LPVOID p)
{
	while(1)
	{
		WaitForSingleObject(msg,INFINITE);

		string buff[5] = {"hello","friend","cool","good","greate"};
		int index = rand()%5;
		goods = buff[index];
		cout<<"produce a msg"<<endl;
		delay();
		
		ReleaseSemaphore(msg, 1, NULL);
	}

	return 0;
}

DWORD WINAPI func2(LPVOID p)
{
	while(1)
	{
		WaitForSingleObject(msg,INFINITE);

		cout<<"consume a msg: "<<goods<<endl;
		delay();
		
		ReleaseSemaphore(msg, 1, NULL);
	}
	return 0;
}

int main()
{
	srand(clock());

	msg = CreateSemaphore(NULL,0,10,NULL);
	ReleaseSemaphore(msg, 1, NULL);

	DWORD TheadId1;
	HANDLE handle1 = CreateThread(NULL, 0, func1, (LPVOID) 8, 0, &TheadId1);
	if (handle1 == false)
	{
		cerr<<"create thread1 fail"<<endl;
		return -1;
	}

	DWORD TheadId2;
	HANDLE handle2 = CreateThread(NULL, 0, func2, (LPVOID) 8, 0, &TheadId2);
	if (handle2 == false)
	{
		cerr<<"create thread2 fail"<<endl;
		return -1;
	}
	WaitForSingleObject(handle1, INFINITE);
	WaitForSingleObject(handle2, INFINITE);

	CloseHandle(handle1);
	CloseHandle(handle2);
	CloseHandle(msg);
	return 0;
}

2、事件

HANDLE CreateEvent(
    LPSECURITY_ATTRIBUTES lpEventAttributes,
    BOOL bManualReset,
    BOOL bInitialState,
    LPCTSTR lpName
);

参数
lpEventAttributes     安全属性。NULL 表示使用默认属性。该属性在Windows 95 中会被忽略。
bManualReset      如为 FALSE,表示这个 event 将在变成激发状态(因而唤醒一个线程)之后,自动重置( reset)为非激发状态。如果是 TRUE,表示不会自动重置,必须靠程序操作(调用ResetEvent() )才能将激发状态的 event 重置为非激发状态。
bInitialState       如为 TRUE ,表示这个 event 一开始处于激发状态。如为 FALSE ,则表示这个 event一开始处于非激发状态。
lpName Event      对象的名称。任何线程或进程都可以根据这个文字名称,使用这一 event 对象。


#include <iostream>
#include <time.h>
#include <string>
#include <Windows.h>

using namespace std;

HANDLE msg;
string goods;

void delay()
{
	int k1 = rand()%30000+1;

	while (k1)
	{
		int k2 = rand()%30000+1;;
		while(k2)
		{
			k2--;
		}
		k1--;
	}
}

DWORD WINAPI func1(LPVOID p)
{
	while(1)
	{
		WaitForSingleObject(msg, INFINITE);

		string buff[5] = {"hello","friend","cool","good","greate"};
		int index = rand()%5;
		goods = buff[index];
		cout<<"produce a msg"<<endl;
		delay();

		SetEvent(msg);
	}

	return 0;
}

DWORD WINAPI func2(LPVOID p)
{
	while(1)
	{
		WaitForSingleObject(msg, INFINITE);

		cout<<"consume a msg: "<<goods<<endl;
		delay();

		SetEvent(msg);
	}
	return 0;
}

int main()
{
	srand(clock());

	msg = CreateEvent(NULL, FALSE, FALSE, NULL);
	SetEvent(msg);

	DWORD TheadId1;
	HANDLE handle1 = CreateThread(NULL, 0, func1, (LPVOID) 8, 0, &TheadId1);
	if (handle1 == false)
	{
		cerr<<"create thread1 fail"<<endl;
		return -1;
	}

	DWORD TheadId2;
	HANDLE handle2 = CreateThread(NULL, 0, func2, (LPVOID) 8, 0, &TheadId2);
	if (handle2 == false)
	{
		cerr<<"create thread2 fail"<<endl;
		return -1;
	}
	WaitForSingleObject(handle1, INFINITE);
	WaitForSingleObject(handle2, INFINITE);

	CloseHandle(handle1);
	CloseHandle(handle2);
	CloseHandle(msg);
	return 0;
}

3、互斥量

HANDLE CreateMutex(
	LPSECURITY_ATTRIBUTES lpMutexAttributes,
	BOOL bInitialOwner,
	LPCTSTR lpName
);

参数
lpMutexAttributes     安全属性。NULL 表示使用默认的属性。这一指定在 Window s 95 中无效。
bInitialOwner       如果你希望“调用 CreateMutex() 的这个线程”拥有产生出来的 mu tex,就将此值设为 TRUE 。
lpName         mu tex 的名称(一个字符串)。任何进程或线程都可以根据此名称使用这一 mu tex。 名称可以是任意字符串,只要不含反斜线(backslash,\)即可。

BOOL ReleaseMutex(
	HANDLE hMutex
);

参数
hMutex       欲释放之 mu tex 的 handle 。

#include <iostream>
#include <time.h>
#include <string>
#include <Windows.h>

using namespace std;

HANDLE msg;
string goods;

void delay()
{
	int k1 = rand()%30000+1;

	while (k1)
	{
		int k2 = rand()%30000+1;;
		while(k2)
		{
			k2--;
		}
		k1--;
	}
}

DWORD WINAPI func1(LPVOID p)
{
	while(1)
	{
		WaitForSingleObject(msg,INFINITE);

		string buff[5] = {"hello","friend","cool","good","greate"};
		int index = rand()%5;
		goods = buff[index];
		cout<<"produce a msg"<<endl;
		delay();

		ReleaseMutex(msg);
	}

	return 0;
}

DWORD WINAPI func2(LPVOID p)
{
	while(1)
	{
		WaitForSingleObject(msg,INFINITE);

		cout<<"consume a msg: "<<goods<<endl;
		delay();

		ReleaseMutex(msg);
	}
	return 0;
}

int main()
{
	srand(clock());

	msg = CreateMutex(NULL,FALSE,NULL);

	DWORD TheadId1;
	HANDLE handle1 = CreateThread(NULL, 0, func1, (LPVOID) 8, 0, &TheadId1);
	if (handle1 == false)
	{
		cerr<<"create thread1 fail"<<endl;
		return -1;
	}

	DWORD TheadId2;
	HANDLE handle2 = CreateThread(NULL, 0, func2, (LPVOID) 8, 0, &TheadId2);
	if (handle2 == false)
	{
		cerr<<"create thread2 fail"<<endl;
		return -1;
	}
	WaitForSingleObject(handle1, INFINITE);
	WaitForSingleObject(handle2, INFINITE);

	CloseHandle(handle1);
	CloseHandle(handle2);
	CloseHandle(msg);
	return 0;
}

4、临界区(线程执行无规律)

VOID InitializeCriticalSection(
	LPCRITICAL_SECTION lpCriticalSection
);

参数
lpCriticalSection     一 个 指 针 , 指 向 欲 被 初 始 化 的CRITICAL_SECTION 变量。这个变量应该在你的程序中定义。

VOID EnterCriticalSection(
	LPCRITICAL_SECTION lpCriticalSection
);

参数
lpCriticalSection     指向一个你即将锁定的 CRITICAL_SECTION 变量。


VOID LeaveCriticalSection(
	LPCRITICAL_SECTION lpCriticalSection
);

参数
lpCriticalSection   指向一个你即将解除锁定的 CRITICAL_SECTION 变量。

#include <iostream>
#include <time.h>
#include <string>
#include <Windows.h>

using namespace std;

CRITICAL_SECTION msg;
string goods;

void delay()
{
	int k1 = rand()%30000+1;

	while (k1)
	{
		int k2 = rand()%30000+1;;
		while(k2)
		{
			k2--;
		}
		k1--;
	}
}

DWORD WINAPI func1(LPVOID p)
{
	while(1)
	{
		EnterCriticalSection(&msg);

		string buff[5] = {"hello","friend","cool","good","greate"};
		int index = rand()%5;
		goods = buff[index];
		cout<<"produce a msg"<<endl;
		delay();

		LeaveCriticalSection(&msg);
	}

	return 0;
}

DWORD WINAPI func2(LPVOID p)
{
	while(1)
	{
		EnterCriticalSection(&msg);

		cout<<"consume a msg: "<<goods<<endl;
		delay();

		LeaveCriticalSection(&msg);
	}
	return 0;
}

int main()
{
	//srand(clock());
	InitializeCriticalSection(&msg);

	DWORD TheadId1;
	HANDLE handle1 = CreateThread(NULL, 0, func1, (LPVOID) 8, 0, &TheadId1);
	if (handle1 == false)
	{
		cerr<<"create thread1 fail"<<endl;
		return -1;
	}

	DWORD TheadId2;
	HANDLE handle2 = CreateThread(NULL, 0, func2, (LPVOID) 8, 0, &TheadId2);
	if (handle2 == false)
	{
		cerr<<"create thread2 fail"<<endl;
		return -1;
	}
	WaitForSingleObject(handle1, INFINITE);
	WaitForSingleObject(handle2, INFINITE);

	CloseHandle(handle1);
	CloseHandle(handle2);
	DeleteCriticalSection(&msg);
	
	return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值