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

#include <stdio.h>#include <process.h>#include <windows.h>volatile long g_nLoginCount; //登录次数unsigned int __stdcall Fun(void *pPM); //线程函数const int THREAD_NUM = 10; //启动线程数unsigned int __stdcall ThreadFun(void *pPM){Sleep(100); //some work should to dog_nLoginCount++;Sleep(50); return 0;}int main(){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;}

和上一篇的线程报数程序一样,程序输出的结果好象并没什么问题。下面我们增加点用户来试试,现在模拟50个用户登录,为了便于观察结果,在程序中将50个用户登录过程重复20次,代码如下:

#include <stdio.h>#include <windows.h>volatile long g_nLoginCount; //登录次数unsigned int __stdcall Fun(void *pPM); //线程函数const DWORD THREAD_NUM = 50;//启动线程数DWORD WINAPI ThreadFun(void *pPM){Sleep(100); //some work should to dog_nLoginCount++;Sleep(50);return 0;}int main(){printf("原子操作 Interlocked系列函数的使用\n");printf(" — by MoreWindows( ) –\n\n");//重复20次以便观察多线程访问同一资源时导致的冲突int num= 20;while (num–){g_nLoginCount = 0;int i;HANDLE handle[THREAD_NUM];for (i = 0; i < THREAD_NUM; i++)handle[i] = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);printf("有%d个用户登录后记录结果是%d\n", THREAD_NUM, g_nLoginCount);}return 0;}

DWORD WINAPI ThreadFun(void *pPM){Sleep(100);//some work should to do//g_nLoginCount++;InterlockedIncrement((LPLONG)&g_nLoginCount);Sleep(50);return 0;}

再次运行,可以发现结果会是唯一的。

因此,在多线程环境下,我们对变量的自增自减这些简单的语句也要慎重思考,防止多个线程导致的数据访问出错。更多介绍,请访问MSDN上Synchronization Functions这一章节,地址为

看到这里,,相信本系列首篇《秒杀多线程第一篇 多线程笔试面试题汇总》中选择题第一题(百度笔试题)应该可以秒杀掉了吧(知其然也知其所以然),正确答案是D。另外给个附加问题,程序中是用50个线程模拟用户登录,有兴趣的同学可以试下用100个线程来模拟一下(上机试试绝对会有意外发现^_^)。

下一篇《秒杀多线程第四篇 一个经典多线程同步问题》将提出一个稍为复杂点但却非常经典的多线程同步互斥问题,这个问题会采用不同的方法来解答,从而让你充分熟练多线程同步互斥的“招式”。更多精彩,欢迎继续参阅。

转载请标明出处,原文地址:

如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。

把你的脸迎向阳光,那就不会有阴影

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

相关文章:

你感兴趣的文章:

标签云: