Windows提高_2.2第二部分:用户区同步
第二部分:用户区同步
同步和互斥
同步:就是按照一定的顺序执行不同的线程
互斥:当一个线程访问某一资源的时候,其它线程不能同时访问
多线程产生的问题
#include <stdio.h>
#include <windows.h>
// 全局变量,被不同的线程访问和修改
int g_Number = ;
DWORD WINAPI ThreadPro1(LPVOID lpThreadParameter)
{
// 为 g_Number 自增 100000 次
for (int i = ; i < ; i++)
g_Number++;
return ;
}
DWORD WINAPI ThreadPro2(LPVOID lpThreadParameter)
{
// 为 g_Number 自增 100000 次
for (int i = ; i < ; i++)
g_Number++;
return ;
}
int main()
{
// 创建两个线程
HANDLE hThread1 = CreateThread(NULL, NULL, ThreadPro1, NULL, NULL, NULL);
HANDLE hThread2 = CreateThread(NULL, NULL, ThreadPro2, NULL, NULL, NULL);
// 等待两个线程执行结束
WaitForSingleObject(hThread1, -);
WaitForSingleObject(hThread2, -);
// 输出修改后的全局变量
printf("%d", g_Number);
return ;
}
产生问题的原因
mov eax, dword ptr[Number]
add eax, 1
mov dword ptr[Number],eax
; C语言的单条语句被翻译成了多条汇编代码,二线程的切换可能导致多条代码分开执行
mov eax, dword ptr[Number] [0]: Number(0) eax(0)
add eax, 1 [0]: Number(0) eax(1)
mov dword ptr[Number],eax [0]: Number(1) eax(1)
mov eax, dword ptr[Number] [1]: Number(1) eax(1)
add eax, 1 [1]: Number(1) eax(2)
mov dword ptr[Number],eax [1]: Number(2) eax(1)
mov eax, dword ptr[Number] [0]: Number(2) eax(2)
add eax, 1 [0]: Number(2) eax(3) -----------
mov eax, dword ptr[Number] [1]: Number(2) eax(2)
add eax, 1 [1]: Number(2) eax(3)
mov dword ptr[Number],eax [1]: Number(3) eax(3)
mov eax, dword ptr[Number] [1]: Number(3) eax(3)
add eax, 1 [1]: Number(3) eax(4)
mov dword ptr[Number],eax [1]: Number(4) eax(4)
mov dword ptr[Number],eax [0]: Number(3) eax(3) -----------
原子操作(Interlocked...)
特点:将一条语句转换成了具有同等功能的单条汇编指令
lock inc dword ptr [Number]
缺点:只能给单个整数类型(4/8)进行保护,不能给使一段代码变成原子操作
函数:
InterlockedXXX
for (int i = ; i < ; i++)
{
// 使用原子操作函数,将自增操作变为不可分割的一条指令
InterlockedIncrement(&g_Number);
// 以上语句会被翻译成下列单条汇编指令
// lock inc dword ptr [g_Number]
}
临界区(CriticalSection)
特点:拥有线程拥有者的概念,同一个线程可以不断的重新进入临界区,但是进入了多少次,就要退出多少。
缺点:一旦拥有临界区的线程崩溃,那么所有等待临界区的线程就会产生死锁。
函数:
初始化: InitializeCriticalSection
保护:EnterCriticalSection
结束保护 :LeaveCriticalSection
删除:DeleteCriticalSection
// 1. 创建一个临界区(关键段)结构体
CRITICAL_SECTION CriticalSection = { };
// 2. 在 【main】 函数中对创建的临界区进行初始化操作
// InitializeCriticalSection(&CriticalSection);
DWORD WINAPI ThreadPro1(LPVOID lpThreadParameter)
{
// 为 g_Number 自增 100000 次
for (int i = ; i < ; i++)
{
// 当有一个线程正在执行代码的时候
// 同一个线程每进入一次受保护的区域,RecursionCount +1
// OwningThread 当前被哪一个线程所有
// 3. 使用 EnterCriticalSection 标识需要保护的代码的起始位置
EnterCriticalSection(&CriticalSection);
g_Number++;
// 4. 使用 LeaveCriticalSection 标识需要保护的代码的结束位置
LeaveCriticalSection(&CriticalSection);
}
return ;
}
Windows提高_2.2第二部分:用户区同步的更多相关文章
- Windows提高_2.3第三部分:内核区同步
第三部分:内核区同步 等待函数(WaitForObject) 等待函数的形式 单个:WaitForSingleObject 多个:WaitForMultipleObjects 一个可以被等待的对象通常 ...
- Windows提高_2.1第一部分:线程
第一部分:线程 什么是线程? 线程其实可以理解为一段正在执行中的代码,它最少由一个线程内核对象和一个栈组成. 线程之间是没有从属关系的,同一进程下的所有线程都可以访问进程内的所有内容. 主线程其实是创 ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- Windows 下目录及文件向Linux同步
本文解决的是Windows 下目录及文件向Linux同步的问题,Windows向 Windows同步的请参考:http://www.idcfree.com/article-852-1.html 环境介 ...
- linux/windows系统oracle数据库简单冷备同步
linux/windows系统oracle数据库简单冷备同步 我们有一个财务系统比较看重财务数据的安全性,同时我们拥有两套系统,一个生产环境(linux),一个应急备份环境(windows).备份环境 ...
- 牛客网NOIP赛前集训营-普及组(第二场)和 牛客网NOIP赛前集训营-提高组(第二场)解题报告
目录 牛客网NOIP赛前集训营-普及组(第二场) A 你好诶加币 B 最后一次 C 选择颜色 D 合法括号序列 牛客网NOIP赛前集训营-提高组(第二场) A 方差 B 分糖果 C 集合划分 牛客网N ...
- ftp客户端自动同步 Windows系统简单操作ftp客户端自动同步
服务器管理工具它是一款功能强大的服务器集成管理器,包含win系统和linux系统的批量连接,vnc客户端,ftp客户端等等实用功能.我们可以使用这款软件的ftp客户端定时上传下载的功能来进实现ftp客 ...
- Windows与Linux之间的文件自动同步
问题:在工作中遇到一个场景,需要每天定时将Linux机器上的文件自动同步到Windows机器上. 解决方案有两个: 1.在Windows 机器上设置共享目录,然后在Linux机器上挂载共享 目录,每天 ...
- windows环境利用semophore机制进行线程同步
semophore是信号量的意思,常用于PV操作,所谓PV操作就是pend(等待,直到有资源可用,并且消耗资源) V就是释放资源. semophore和mutex区别,mutex本意为互斥,用于线程独 ...
随机推荐
- MongoDB Helper的简单封装
db.properties #mongodb数据库配置文件 #数据库server所在的ip地址 ip=127.0.0.1 #mongodb服务port号 port=27017 #要连接的库 dbNa ...
- zipfile zip
Python模块学习:zipfile zip文件操作 2015/05/27 · 系列教程 · zipfile 分享到:3 原文出处: DarkBull 最近在写一个网络客户端下载程序,用于下载服 ...
- Redis缓存数据库安全加固指导(二)
背景 在众多开源缓存技术中,Redis无疑是目前功能最为强大,应用最多的缓存技术之一,参考2018年国外数据库技术权威网站DB-Engines关于key-value数据库流行度排名,Redis暂列第一 ...
- skype默认占用80和443port
今天把server的port更改为80,结果起不来,报告"port已经被占用"的错误. 使用下列命令找到了元凶: 1. netstat -ano | findstr 80 找到占用 ...
- Android 4.4.2 动态加入JNI库方法记录 (一 JNI库层)
欢迎转载,务必注明出处.http://blog.csdn.net/wang_shuai_ww/article/details/44456755 本篇是继<s5p4418 Android 4.4. ...
- leetcode第一刷_Search in Rotated Sorted Array
旋转数组的查找问题.从头開始扫一遍.O(N)的复杂度,一般也能过,甚至先排序下面,再二分都能过.只是这道题的目的当然不在于此. 想一下旋转之后对我们的查找产生了什么影响.假设没旋转过,我们直接比較ta ...
- 使用MyBatis Generator自动生成MyBatis的代码
这两天需要用到MyBatis的代码自动生成的功能,由于MyBatis属于一种半自动的ORM框架,所以主要的工作就是配置Mapping映射文件,但是由于手写映射文件很容易出错,所以可利用MyBatis生 ...
- 训练深度学习网络时候,出现Nan是什么原因,怎么才能避免?——我自己是因为data有nan的坏数据,clear下解决
from:https://www.zhihu.com/question/49346370 Harick 梯度爆炸了吧. 我的解决办法一般以下几条:1.数据归一化(减均值,除方差,或者加入n ...
- go语言--time.After
go语言--time.After https://blog.csdn.net/cyk2396/article/details/78873396 1.源码分析: // After waits for t ...
- [Codeforces Round511C] Enlarge GCD
[题目链接] https://codeforces.com/contest/1047/problem/C [算法] 首先求出n个数的最大公约数g , 将每个数除以g , 那么 , 问题就转化为在n个数 ...