【多线程】(二)Interlocked系列函数

参考自 http://blog.csdn.net/morewindows/article/details/7429155

 

// Thread02.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <process.h>
#include <windows.h>

volatile long g_nLoginCount;
unsigned int __stdcall Fun(void *pPM);
const int THREAD_NUM = 50;
unsigned int __stdcall ThreadFun(void *pPM)
{
	Sleep(100);
	g_nLoginCount++;
	Sleep(50);
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int num = 40;
	while(num--)
	{
		g_nLoginCount = 0;
		HANDLE handle[THREAD_NUM];
		for (int i = 0;i<THREAD_NUM ;i++)
		{
			handle[i] = (HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,NULL);
		}
		WaitForMultipleObjects(THREAD_NUM,handle ,TRUE ,INFINITE);
		printf("有%d个用户登录后记录结果是%d\n",THREAD_NUM,g_nLoginCount);
	}

	return 0;
}

运行结果

 

由于线程执行的并发性,很可能线程A执行到第二句时,线程B开始执行,线程B将原来的值又写入寄存器eax中,这样线程A所主要计算的值就被线程B修改了。这样执行下来,结果是不可预知的——可能会出现50,可能小于50

       因此在多线程环境中对一个变量进行读写时,我们需要有一种方法能够保证对一个值的递增操作是原子操作——即不可打断性,一个线程在执行原子操作时,其它线程必须等待它完成之后才能开始执行该原子操作。这种涉及到硬件的操作会不会很复杂了,幸运的是,Windows系统为我们提供了一些以Interlocked开头的函数来完成这一任务(下文将这些函数称为Interlocked系列函数)。

下面列出一些常用的Interlocked系列函数:

1.增减操作

LONG__cdeclInterlockedIncrement(LONG volatile* Addend);

LONG__cdeclInterlockedDecrement(LONG volatile* Addend);

返回变量执行增减操作之后的值

LONG__cdec InterlockedExchangeAdd(LONG volatile* Addend, LONGValue);

返回运算后的值,注意!加个负数就是减。

 

2.赋值操作

LONG__cdeclInterlockedExchange(LONG volatile* Target, LONGValue);

Value就是新值,函数会返回原先的值。

 

修改代码为:

unsigned int __stdcall ThreadFun(void *pPM)
{
	Sleep(100);
	//g_nLoginCount++;
	InterlockedIncrement((LPLONG)&g_nLoginCount);
	Sleep(50);
	return 0;
}


 

将THREAD_NUM = 100;

则结果如下

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值