windows程序设计(第2版 王艳平)学习记要:3.2 线程同步

线程同步的主要问题,在于需要解决不止一个线程同时执行某一段代码,访问同一个内存中的数据,临界区对象就是为了解决这个问题,它是一个CRITICAL_SECYION结构,被windows内部使用这个结构记录一些信息,确保同一时间只有一个线程访问该数据段中的数据

临界对象的代码示例

///
// CriticalSection.cpp文件

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

BOOL g_bContinue = TRUE;
int g_nCount1 = 0;
int g_nCount2 = 0;
CRITICAL_SECTION g_cs; // 对存在同步问题的代码段使用临界区对象

UINT __stdcall ThreadFunc(LPVOID);

int main(int argc, char* argv[])
{
	UINT uId;
	HANDLE h[2];

	
	::InitializeCriticalSection(&g_cs);   // 初始化临界区对象,g_cs是一个LP指针,指向CRITICAL_SECTION结构

	h[0] = (HANDLE)::_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &uId);
	h[1] = (HANDLE)::_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &uId);

	// 等待1秒后通知两个计数线程结束,关闭句柄
	Sleep(1000);
	g_bContinue = FALSE;
	::WaitForMultipleObjects(2, h, TRUE, INFINITE);
	::CloseHandle(h[0]);
	::CloseHandle(h[1]);

	// 删除临界区对象,临界对象使用完后一定要删除,以免内存泄漏
	::DeleteCriticalSection(&g_cs);
	
	printf("g_nCount1 = %d \n", g_nCount1);
	printf("g_nCount2 = %d \n", g_nCount2);

	return 0;
}

UINT __stdcall ThreadFunc(LPVOID)
{
	while(g_bContinue)
	{
		::EnterCriticalSection(&g_cs);              //进入临界对象,同一时间,只允许一个线程进入
		g_nCount1++;
		g_nCount2++;
		::LeaveCriticalSection(&g_cs);             //离开临界对象,表示临界对象现在可以被其它线程进入
	}
	return 0;
}

互锁函数

互锁函数的远离比较简单,基本规则是,它自增或者自减变量时,阻止其它线程同时使用该变量

事件内核对象

这东西主要用于线程之间互相通信,告知工作状态和控制信号。比如事件对象就是用于这个范畴的

事件对象由CreatEvent创建

信号量内核对象

信号量允许超过一个以上的线程同时访问一个资源,但是他有线程数量上限的限制

互斥内核对象

这玩意和临界区对象最大的不同是它是内核对象,由系统管理,它可以跨越进程,临界区不行,临界区性能高资源占用少,互斥对象性能低,资源消耗大
http://blogold.chinaunix.net/u2/86649/showart.php?id=1672176

3.2.6 线程局部存储

英文名称TLS,和线程关联的数据结构,可以利用其获取线程的生命周期,不过老实说还是不太清楚这样做的特殊意义,以后遇上了,再说吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值