秒杀多线程第四篇一个经典的多线程同步问题(代码片段)

heishanglaoyao heishanglaoyao     2022-11-24     649

关键词:

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

 

程序描述:

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

要求:

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

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

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

技术分享图片

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

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

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

 

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

//经典线程同步互斥问题
#include <stdio.h>
#include <process.h>
#include <windows.h>

long g_nNum; //全局资源
unsigned int __stdcall Fun(void *pPM); //线程函数
const int THREAD_NUM = 10; //子线程个数

int main()

	g_nNum = 0;
	HANDLE  handle[THREAD_NUM];
	
	int i = 0;
	while (i < THREAD_NUM) 
	
		handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
		i++;//等子线程接收到参数时主线程可能改变了这个i的值
	
	//保证子线程已全部运行结束
	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);  
	return 0;


unsigned int __stdcall Fun(void *pPM)

//由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来
	int nThreadNum = *(int *)pPM; //子线程获取参数
	Sleep(50);//some work should to do
	g_nNum++;  //处理全局资源
	Sleep(0);//some work should to do
	printf("线程编号为%d  全局资源值为%d
", nThreadNum, g_nNum);
	return 0;

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

1

技术分享图片

2

技术分享图片

3

技术分享图片

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

 

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

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

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

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

 

 

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

 

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

秒杀多线程第七篇经典线程同步互斥量mutex(代码片段)

阅读本篇之前推荐阅读以下姊妹篇:《秒杀多线程第四篇一个经典的多线程同步问题》《秒杀多线程第五篇经典线程同步关键段CS》《秒杀多线程第六篇经典线程同步事件Event》 前面介绍了关键段CS、事件Event在经典线程同步... 查看详情

秒杀多线程第八篇经典线程同步信号量semaphore(代码片段)

阅读本篇之前推荐阅读以下姊妹篇:《秒杀多线程第四篇一个经典的多线程同步问题》《秒杀多线程第五篇经典线程同步关键段CS》《秒杀多线程第六篇经典线程同步事件Event》《秒杀多线程第七篇经典线程同步互斥量Mutex》 ... 查看详情

经典线程同步信号量semaphore

阅读本篇之前推荐阅读以下姊妹篇:《秒杀多线程第四篇一个经典的多线程同步问题》《秒杀多线程第五篇经典线程同步关键段CS》《秒杀多线程第六篇经典线程同步事件Event》《秒杀多线程第七篇经典线程同步互斥量Mutex》 ... 查看详情

秒杀多线程第十二篇多线程同步内功心法——pv操作上

阅读本篇之前推荐阅读以下姊妹篇:《秒杀多线程第四篇一个经典的多线程同步问题》《秒杀多线程第五篇经典线程同步关键段CS》《秒杀多线程第六篇经典线程同步事件Event》《秒杀多线程第七篇经典线程同步互斥量Mutex》《秒... 查看详情

经典线程同步关键段cs

上一篇《秒杀多线程第四篇一个经典的多线程同步问题》提出了一个经典的多线程同步互斥问题,本篇将用关键段CRITICAL_SECTION来尝试解决这个问题。本文首先介绍下如何使用关键段,然后再深层次的分析下关键段的实现机制与... 查看详情

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

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

秒杀多线程第八篇经典线程同步信号量semaphore

前面介绍了关键段CS、事件Event、互斥量Mutex在经典线程同步问题中的使用。本篇介绍用信号量Semaphore来解决这个问题。首先也来看看如何使用信号量,信号量Semaphore常用有三个函数,使用很方便。下面是这几个函数的原型和使用... 查看详情

秒杀多线程第十篇生产者消费者问题(代码片段)

   继经典线程同步问题之后,我们来看看生产者消费者问题及读者写者问题。生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了... 查看详情

秒杀多线程第三篇原子操作interlocked系列函数(代码片段)

上一篇《多线程第一次亲密接触CreateThread与_beginthreadex本质区别》中讲到一个多线程报数功能。为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是否运行出错。这也非常类似于统计一个网站每天有多少... 查看详情

秒杀多线程第十一篇读者写者问题(代码片段)

与上一篇《秒杀多线程第十篇生产者消费者问题》的生产者消费者问题一样,读者写者也是一个非常著名的同步问题。读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读... 查看详情

秒杀多线程第一篇多线程笔试面试题汇总

...”,相信你也能对多线程挥洒自如,在笔试面试中顺利的秒杀多 查看详情

秒杀多线程第二篇多线程第一次亲密接触createthread与_beginthreadex本质区别(代码片段)

   本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_beginthreadex的本质区别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beginthreadex到底有什么区别,在实际的编程中到底... 查看详情

秒杀多线程面试题系列

【专栏】-秒杀多线程面试题系列-MoreWindowsBlog(格物穷理,以求自由!)-CSDN博客   PV原语操作详解-Benson_xiong-博客园    查看详情

21天学习挑战赛python学习第四篇:多线程threading模块(代码片段)

​【21天学习挑战赛】Python学习第四篇:多线程threading模块——活动地址:CSDN21天学习挑战赛——多线程的理解就是两件或两件以上的事情通过代码同时发生。而一般情况下我们写python代码的话是从上往下执行的,有... 查看详情

经典同步问题总结(代码片段)

...进行操作解法一:读者优先存在的问题:如果有一个读者线程在读,那么之后如果同时来了读线程和写线程,读线程会优先执行      可能会导致写线程长时间等待。1intcount=0;//用于记录当前的读者数量2semaphoremutex=1;//用... 查看详情

秒杀多线程系列中的题目

1.什么是线程安全?(2012年5月百度实习生面试)  如果多线程的程序运行结果是可预期的,而且与单线程的程序运行结果一样,那么说明是“线程安全”的。 a.线程的概念、线程的基本状态及状态之间的关系    另外... 查看详情

linux篇第十四篇——多线程(线程同步和互斥+线程安全+条件变量)(代码片段)

⭐️本篇博客开始要继续给大家介绍线程同步和互斥相关的知识。多线程是如何进行同步与互斥操作的,下面我来和大家一起聊一聊~目录🌏线程互斥🌲概念🌲互斥量mutex🌲互斥量的接口🌲互斥量的原理&... 查看详情

第四篇:断路器(hystrix)(代码片段)

...00%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完 查看详情