秒杀多线程第三篇 原子操作 Interlocked系列函数 .

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

本想以该博客的指示编写程序找出漏洞,但是却没有发现异常

//创建多子个线程实例
#include <stdio.h>
#include <process.h>
#include <windows.h>

volatile long g_nLoginCount=0; //登录次数 
const int THREAD_NUM = 55; //启动线程数 
//子线程函数
unsigned int __stdcall ThreadFun1(PVOID pM)
{
	Sleep(100);
	g_nLoginCount++;
	printf("线程号是:%4d 该线程说:%d\n",GetCurrentThreadId(),g_nLoginCount);
	Sleep(50);
	return 0;
}

int main()
{	
	int num=20;//循环20次,以便找出错误
	while (num--)
	{
		HANDLE handle[THREAD_NUM];
		for(int i=0;i<THREAD_NUM;i++)
			handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun1, NULL, 0, NULL);
		WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
		printf("%d\n",g_nLoginCount);
		
	}
	return 0;
}

 运行参考 博客的程序找出了漏洞

 1 #include <stdio.h>
 2 #include <windows.h>
 3 volatile long g_nLoginCount; //登录次数
 4 unsigned int __stdcall Fun(void *pPM); //线程函数
 5 const DWORD THREAD_NUM = 50;//启动线程数
 6 DWORD WINAPI ThreadFun(void *pPM)
 7 {
 8     Sleep(100); //some work should to do
 9     g_nLoginCount++;
10     Sleep(50);
11     return 0;
12 }
13 int main()
14 {
15     printf("     原子操作 Interlocked系列函数的使用\n");
16     printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
17     
18     //重复20次以便观察多线程访问同一资源时导致的冲突
19     int num= 20;
20     while (num--)
21     {    
22         g_nLoginCount = 0;
23         int i;
24         HANDLE  handle[THREAD_NUM];
25         for (i = 0; i < THREAD_NUM; i++)
26             handle[i] = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);
27         WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
28         printf("有%d个用户登录后记录结果是%d\n", THREAD_NUM, g_nLoginCount);
29     }
30     return 0;
31 }

 运行结果:

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就是新值,函数会返回原先的值。

只将支线程的服务函数换成Interlocked系列函数即可

 

1 DWORD WINAPI ThreadFun(void *pPM)
2 {
3     Sleep(100); //some work should to do
4 //    g_nLoginCount++;
5     InterlockedIncrement((LPLONG)&g_nLoginCount);
6     Sleep(50);
7     return 0;
8 }
原文地址:https://www.cnblogs.com/yuqilihualuo/p/3021792.html