`

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

 
阅读更多

本篇文章参考了http://blog.csdn.net/morewindows/article/details/7442333

 

程序描述:

主线程启动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\n", nThreadNum, g_nNum);
	return 0;
}

运行结果可以参考下列图示,


 


 



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

  • 大小: 57.1 KB
  • 大小: 8.3 KB
  • 大小: 8.3 KB
  • 大小: 8.3 KB
分享到:
评论

相关推荐

    多线程代码 经典线程同步互斥问题 生产者消费者问题

    d: 经典线程同步互斥问题 e: 使用关键段解决子线程互斥问题 f: 利用事件实现线程同步问题 g: 利用互斥量来解决线程同步互斥问题 h: problem1 生产者消费者问题 (1生产者 1消费者 1缓冲区) problem1 more ...

    解决多线程编程中的同步互斥问题

    在Windows平台下,解决多线程同步互斥问题的一种常用方法是使用关键段(Critical Section)。关键段是一种轻量级的同步对象,用于保护共享资源免受并发访问的影响。一旦一个线程获得了对某个关键段的所有权,其他...

    Jni多线程同步事例

    在本例“Jni多线程同步事例”中,我们将探讨如何在JNI层面上实现多线程同步,特别是在一个生产者-消费者模型的场景下。 生产者-消费者模型是一种经典的并发问题,它涉及到两个或多个线程之间的协作。在该模型中,...

    用多线程同步方法解决生产者-消费者问题

    生产者-消费者问题是多线程同步的一个经典案例,主要探讨如何在并发环境下,确保生产者进程和消费者进程之间正确地共享资源,避免数据竞争和死锁。在这个问题中,生产者进程负责创建产品并将产品放入缓冲区,而消费...

    秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据

    在《秒杀多线程系列》的前十五篇中介绍多线程的相关概念,多线程同步互斥问题《秒杀多线程第四篇一个经典的多线程同步问题》及解决多线程同步互斥的常用方法——关键段、事件、互斥量、信号量、读写锁。为了让大家...

    操作系统实验中的线程同步问题

    标题中提到的"操作系统实验中的线程同步问题"是指在实验环境下,通过模拟多线程环境来研究和解决线程并发访问共享资源时可能出现的问题。这类问题通常会导致数据混乱、死锁或系统性能下降。解决这些问题的方法包括...

    操作系统线程同步算法

    操作系统中的线程同步是多线程编程中一个关键的概念,它确保了多个线程在访问共享资源时的正确性,防止数据竞争和其他并发问题。在Windows操作系统中,提供了多种线程同步机制,如临界区、事件、信号量以及互斥量等...

    11-线程同步

    "哲学家就餐"问题是一个经典的多线程同步问题,描述了五个哲学家围坐在一张圆桌旁,每个人都需要同时使用左右两边的筷子来吃饭。如果不加控制,可能会出现饿死的情况,即某些哲学家一直无法获取到筷子。解决这个问题...

    多线程_按键精灵经典多线程操作_

    标题“多线程_按键精灵经典多线程操作_”表明我们将探讨的是如何在按键精灵这款自动化工具中实现多线程的功能。按键精灵是一款功能强大的自动化软件,它可以模拟用户的键盘和鼠标操作,执行一系列预定义的任务,如...

    哲学家就餐问题是一个经典的同步问题,用多线程编程实现哲学家就餐问题

    哲学家就餐问题(Dining Philosophers Problem)是计算机科学中多线程与并发控制领域的一个经典示例,由美国计算机科学家Edsger Dijkstra在1965年提出。这个问题模拟了五个哲学家围坐在一张圆桌旁,每个人面前都有一...

    用多线程同步方法解决哲学家就餐问题

    【哲学家就餐问题】是操作系统领域中的一个经典问题,它涉及到多线程同步和死锁的预防。在这个问题中,有5位哲学家坐在一张圆桌旁,每个人左右两边各有一只筷子。为了吃饭,哲学家需要同时拿起左右两边的筷子。如果...

    JAVA实现线程间同步与互斥生产者消费者问题

    在Java编程中,线程同步和互斥是多线程编程中的重要概念,它们用于解决多个线程同时访问共享资源时可能出现的问题。本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费...

    用多线程同步方法解决哲学家就餐问题.zip

    在计算机科学领域,多线程同步是解决并发问题的关键技术之一。这个实验“用多线程同步方法解决哲学家就餐问题”旨在让学生深入理解多线程编程中的资源竞争与死锁问题,并掌握如何通过同步机制来避免这些问题。在这个...

    多线程并发同步(爸爸妈妈苹果橘子问题,有界面)

    这个主题通过一个生动的“爸爸妈妈苹果橘子问题”来解释,这是一个经典的多线程同步问题,有助于理解线程间如何协作共享资源。在这个场景中,爸爸负责放入苹果,妈妈负责放入橘子,而儿子负责吃苹果,女儿负责吃橘子...

    经典进程同步问题(代码+文档)

    本资料包“经典进程同步问题(代码+文档)”专注于讲解和实现三个经典的进程同步问题,这些问题在多线程编程中尤为重要。这些问题在Linux环境下通过两种信号量机制得以解决,这意味着我们将探讨P/V操作以及互斥信号...

    用多线程同步方法解决生产者-消费者问题(操作系统课设

    多线程同步方法解决生产者-消费者问题 多线程同步方法是解决生产者-消费者问题的常用方法。生产者-消费者问题是操作系统中经典的问题之一,它是指在多线程环境下,多个生产者线程和消费者线程访问同一个共享缓冲区...

    经典进程同步问题

    在操作系统领域,进程同步是多线程或多进程环境下确保数据一致性、避免竞态条件和死锁等问题的关键技术。本文将深入探讨"经典进程同步问题",以C/C++语言为实现工具,通过三个简单易懂的程序来阐述相关概念。 首先...

    线程经典问题代码

    这里我们关注的是一个经典的多线程问题——生产者-消费者问题。这个问题是计算机科学中并发编程的一个基础模型,它展示了如何有效地在多个线程之间共享资源。 生产者-消费者问题是这样的:一个或多个“生产者”线程...

Global site tag (gtag.js) - Google Analytics