• 一个经典的多线程同步问题


    上一篇《秒杀多线程第三篇原子操作 Interlocked系列函数》中介绍了原子操作在多进程中的作用,现在来个复杂点的。这个问题涉及到线程的同步和互斥,是一道非常有代表性的多线程同步问题,如果能将这个问题搞清楚,那么对多线程同步也就打下了良好的基础。

     

    程序描述:

    主线程启动10个子线程并将表示子线程序号的变量地址作为参数传递给子线程。子线程接收参数 -> sleep(50) -> 全局变量++ -> sleep(0) -> 输出参数和全局变量。

    要求:

    1.子线程输出的线程序号不能重复。

    2.全局变量的输出必须递增。

    下面画了个简单的示意图:

    分析下这个问题的考察点,主要考察点有二个:

    1.主线程创建子线程并传入一个指向变量地址的指针作参数,由于线程启动须要花费一定的时间,所以在子线程根据这个指针访问并保存数据前,主线程应等待子线程保存完毕后才能改动该参数并启动下一个线程。这涉及到主线程与子线程之间的同步

    2.子线程之间会互斥的改动和输出全局变量。要求全局变量的输出必须递增。这涉及到各子线程间的互斥

     

    下面列出这个程序的基本框架,可以在此代码基础上进行修改和验证。

    [cpp] view plain copy
     
    1. //经典线程同步互斥问题  
    2. #include <stdio.h>  
    3. #include <process.h>  
    4. #include <windows.h>  
    5.   
    6. long g_nNum; //全局资源  
    7. unsigned int __stdcall Fun(void *pPM); //线程函数  
    8. const int THREAD_NUM = 10; //子线程个数  
    9.   
    10. int main()  
    11. {  
    12.     g_nNum = 0;  
    13.     HANDLE  handle[THREAD_NUM];  
    14.       
    15.     int i = 0;  
    16.     while (i < THREAD_NUM)   
    17.     {  
    18.         handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);  
    19.         i++;//等子线程接收到参数时主线程可能改变了这个i的值  
    20.     }  
    21.     //保证子线程已全部运行结束  
    22.     WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);    
    23.     return 0;  
    24. }  
    25.   
    26. unsigned int __stdcall Fun(void *pPM)  
    27. {  
    28. //由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来  
    29.     int nThreadNum = *(int *)pPM; //子线程获取参数  
    30.     Sleep(50);//some work should to do  
    31.     g_nNum++;  //处理全局资源  
    32.     Sleep(0);//some work should to do  
    33.     printf("线程编号为%d  全局资源值为%d ", nThreadNum, g_nNum);  
    34.     return 0;  
    35. }  

    运行结果可以参考下列图示,强烈建议读者亲自试一试。

    图1

    图2

    图3

    可以看出,运行结果完全是混乱和不可预知的。本系列将会运用Windows平台下各种手段包括关键段,事件,互斥量,信号量等等来解决这个问题并作一份全面的总结,敬请关注。

     

    秒杀多线程第五篇 经典线程同步 关键段CS》已经发布,欢迎参阅。

    秒杀多线程第六篇 经典线程同步 事件Event》已经发布,欢迎参阅。

    秒杀多线程第七篇 经典线程同步 互斥量Mutex》已经发布,欢迎参阅。

    秒杀多线程第八篇 经典线程同步 信号量Semaphore》已经发布,欢迎参阅。 

     

     

    转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7442333

     

  • 相关阅读:
    poj 2763 Housewife Wind
    hdu 3966 Aragorn's Story
    poj 1655 Balancing Act 求树的重心
    有上下界的网络流问题
    URAL 1277 Cops and Thieves 最小割 无向图点带权点连通度
    ZOJ 2532 Internship 网络流求关键边
    ZOJ 2760 How Many Shortest Path 最大流+floyd求最短路
    SGU 438 The Glorious Karlutka River =) 拆点+动态流+最大流
    怎么样仿写已知网址的网页?
    5-10 公路村村通 (30分)
  • 原文地址:https://www.cnblogs.com/zsq1993/p/5982504.html
Copyright © 2020-2023  润新知