四种进程或线程同步互斥的控制方法:
1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 
2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 
3、信号量:为控制一个具有有限数量用户资源而设计。 
4、事件:   用来通知线程有一些事件已发生,从而启动后继任务的开始。

临界区(Critical Section)(同一个进程内,实现互斥,但,无法实现同步,因为其具有“线程所有权”

#include "stdafx.h"

#include <stdio.h>
#include <process.h>
#include <windows.h> long g_nNum; //全局变量
unsigned int __stdcall Fun(void *pPM); //线程函数
const int THREAD_NUM = ; //子线程个数 CRITICAL_SECTION g_cs1;
CRITICAL_SECTION g_cs2; int _tmain(int argc, _TCHAR* argv[])
{
g_nNum = ;
HANDLE handle[THREAD_NUM];
InitializeCriticalSection(&g_cs1);
InitializeCriticalSection(&g_cs2);
int i = ;
while (i < THREAD_NUM)
{
EnterCriticalSection(&g_cs1);
handle[i] = (HANDLE)_beginthreadex(NULL, , Fun, &i, , NULL);
i++;//等子线程接收到参数时主线程可能改变了这个i的值
}
//保证子线程已全部运行结束
WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); DeleteCriticalSection(&g_cs1);
DeleteCriticalSection(&g_cs2); system("pause");
return ;
}
unsigned int __stdcall Fun(void *pPM)
{
//由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来
int nThreadNum = *(int *)pPM; //子线程获取参数
LeaveCriticalSection(&g_cs1);
Sleep();//some work should to do
EnterCriticalSection(&g_cs2);
g_nNum++; //处理全局资源
Sleep();//some work should to do
printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum);
LeaveCriticalSection(&g_cs2);
return ;
}

保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

可以将临界区比作旅馆的房卡,调用EnterCriticalSection()即申请房卡,得到房卡后自己当然是可以多次进出房间的,在你调用LeaveCriticalSection()交出房卡之前,别人自然是无法进入该房间,在经典线程同步问题上,主线程正是由于拥有“线程所有权”即房卡,所以它可以重复进入关键代码区域从而导致子线程在接收参数之前主线程就已经修改了这个参数。所以关键段可以用于线程间的互斥,但不可以用于同步。

互斥量(Mutex)(可以跨进程,实现互斥)
互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。
互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。

信号量(Semaphores)(主要是实现同步,可以跨进程)
信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目,不能在允许其他线程的进入,此时的信号量信号将无法发出

事件(Event)(实现同步,可以跨进程)
事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。

CPP-基础:windows api 多线程---互斥量、信号量、临界值、事件区别的更多相关文章

  1. [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程

    一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...

  2. OS: 读者写者问题(写者优先+LINUX+多线程+互斥量+代码)(转)

    一. 引子 最近想自己写个简单的 WEB SERVER ,为了先练练手,熟悉下在LINUX系统使用基本的进程.线程.互斥等,就拿以前学过的 OS 问题开开刀啦.记得当年学读者写者问题,尤其是写者优先的 ...

  3. windows api多线程

    windows api多线程  原文地址:https://www.cnblogs.com/flowingwind/p/8452693.html 线程是程序中一个单一的顺序控制流程.在单个程序中同时运行 ...

  4. Linux 多线程互斥量互斥

    同步 同一个进程中的多个线程共享所在进程的内存资源,当多个线程在同一时刻同时访问同一种共享资源时,需要相互协调,以避免出现数据的不一致和覆盖等问题,线程之间的协调和通信的就叫做线程的同步问题, 线程同 ...

  5. posix多线程--互斥量

    多线程程序在线程间共享数据时,如果多个线程同时访问共享数据就可能有问题.互斥量是解决多个线程间共享数据的方法之一. 1.互斥量初始化两种方式:(1)静态初始化 #include <pthread ...

  6. linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题

    生产者消费者问题,又有界缓冲区问题.两个进程共享一个一个公共的固定大小的缓冲区.其中一个是生产者,将信息放入缓冲区,另一个是消费者,从缓冲区中取信息. 问题的关键在于缓冲区已满,而此时生产者还想往其中 ...

  7. Linux驱动多线程 - 互斥量

    1.内核多线程相关内容 1.1 头文件#include <linux/kthread.h> 1.2 定义/初始化变量 struct mutex SPI_work; /*定义互斥体*/ mu ...

  8. CPP-基础:互斥量

    互斥量的用途和临界区很像.它与临界区的差别在于可以跨线程使用,可以用来同步进行多个线程间的数据访问,但是是以牺牲速度为代价的.只有临界区是非核心对象,那么互斥量就是一个核心对象了.核心对象的特点是有所 ...

  9. Delphi线程同步(临界区、互斥、信号量)

    当有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源. 例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件的字符数.当然,在整个文件调入内存之前,统计它的计数是 ...

随机推荐

  1. 2 手写Java LinkedList核心源码

    上一章我们手写了ArrayList的核心源码,ArrayList底层是用了一个数组来保存数据,数组保存数据的优点就是查找效率高,但是删除效率特别低,最坏的情况下需要移动所有的元素.在查找需求比较重要的 ...

  2. 使用fastadmin的页面异常模板

    1.效果图 2.修改tp异常页面的模板文件( /thinkphp/tpl/think_exception.tpl ),将文件中的内容全部替换成下面的内容然后保存即可(若发生报错,请注意语言包问题) & ...

  3. POJ2752【KMP-next数组含义】

    题意: 给一个字符串,求满足既是这个字符串的前缀,又是这个字符串的后缀,从小到大输出长度 思路: 细讲next数组含义博文:点我 首先要满足前缀的呀. KMP的next数组干的是子串最长后缀. 所以从 ...

  4. JToken和JObject有什么区别

    JObject  用于操作JSON对象JArray    用语操作JSON数组JValue   表示数组中的值JProperty 表示对象中的属性,以"key/value"形式JT ...

  5. IM 通讯录

    wkt-4024 6720

  6. tcp端口扫描(python多线程)

    1 使用单线程扫描单台主机 首先实现的是对单台主机中0-1024端口的扫描,发现差不多每秒扫描一个端口,很慢. import socket def tcp_scanner(host,port): cl ...

  7. Linux下Java运行.class文件,报错找不到或无法加载主类

    classpath配置的错误,所以找不到.class文件. 原先的etc/profile中的classpath配置 export CLASSPATH=$JAVA_HOME/lib/tools.jar ...

  8. 107 Binary Tree Level Order Traversal II 二叉树的层次遍历 II

    给定一个二叉树,返回其节点值自底向上的层次遍历. (即按从叶节点所在层到根节点所在的层,逐层从左向右遍历)例如:给定二叉树 [3,9,20,null,null,15,7],    3   / \  9 ...

  9. git stash暂存当前正在进行的工作

    git stash 可用来暂存当前正在进行的工作, 比如想pull 最新代码, 又不想加新commit, 或者另外一种情况,为了fix 一个紧急的bug,  先stash, 使返回到自己上一个comm ...

  10. 获取span里面的值(特殊情况下 )

    如何获取A? <div class="warpper"> <span class="content"> A <span>12 ...