第二部分:用户区同步

同步和互斥

  • 同步:就是按照一定的顺序执行不同的线程

  • 互斥:当一个线程访问某一资源的时候,其它线程不能同时访问

多线程产生的问题

#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第二部分:用户区同步的更多相关文章

  1. Windows提高_2.3第三部分:内核区同步

    第三部分:内核区同步 等待函数(WaitForObject) 等待函数的形式 单个:WaitForSingleObject 多个:WaitForMultipleObjects 一个可以被等待的对象通常 ...

  2. Windows提高_2.1第一部分:线程

    第一部分:线程 什么是线程? 线程其实可以理解为一段正在执行中的代码,它最少由一个线程内核对象和一个栈组成. 线程之间是没有从属关系的,同一进程下的所有线程都可以访问进程内的所有内容. 主线程其实是创 ...

  3. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  4. Windows 下目录及文件向Linux同步

    本文解决的是Windows 下目录及文件向Linux同步的问题,Windows向 Windows同步的请参考:http://www.idcfree.com/article-852-1.html 环境介 ...

  5. linux/windows系统oracle数据库简单冷备同步

    linux/windows系统oracle数据库简单冷备同步 我们有一个财务系统比较看重财务数据的安全性,同时我们拥有两套系统,一个生产环境(linux),一个应急备份环境(windows).备份环境 ...

  6. 牛客网NOIP赛前集训营-普及组(第二场)和 牛客网NOIP赛前集训营-提高组(第二场)解题报告

    目录 牛客网NOIP赛前集训营-普及组(第二场) A 你好诶加币 B 最后一次 C 选择颜色 D 合法括号序列 牛客网NOIP赛前集训营-提高组(第二场) A 方差 B 分糖果 C 集合划分 牛客网N ...

  7. ftp客户端自动同步 Windows系统简单操作ftp客户端自动同步

    服务器管理工具它是一款功能强大的服务器集成管理器,包含win系统和linux系统的批量连接,vnc客户端,ftp客户端等等实用功能.我们可以使用这款软件的ftp客户端定时上传下载的功能来进实现ftp客 ...

  8. Windows与Linux之间的文件自动同步

    问题:在工作中遇到一个场景,需要每天定时将Linux机器上的文件自动同步到Windows机器上. 解决方案有两个: 1.在Windows 机器上设置共享目录,然后在Linux机器上挂载共享 目录,每天 ...

  9. windows环境利用semophore机制进行线程同步

    semophore是信号量的意思,常用于PV操作,所谓PV操作就是pend(等待,直到有资源可用,并且消耗资源) V就是释放资源. semophore和mutex区别,mutex本意为互斥,用于线程独 ...

随机推荐

  1. 操作系统——IO管理

    一.IO系统结构 在计算机系统中.cpu要和很多外设进行交互.比方鼠标,键盘,网卡等等. 1.IO是怎样协调工作的那? (1)对于设备来说,其有两部分组成,一部分是机械部分,还有一部分是电子控制部分. ...

  2. Mariadb galera 集群

    部署galera 多主架构 (galera集群多用于关键性业务,因为galera集群为了数据的一致性,采用的是同步的机制,这就使galera牺牲了一部分性能来换取数据一致性.) 环境准备:三台服务器 ...

  3. (六)Net Core项目使用Controller之一 c# log4net 不输出日志 .NET Standard库引用导致的FileNotFoundException探究 获取json串里的某个属性值 common.js 如何调用common.js js 筛选数据 Join 具体用法

    (六)Net Core项目使用Controller之一 一.简介 1.当前最流行的开发模式是前后端分离,Controller作为后端的核心输出,是开发人员使用最多的技术点. 2.个人所在的团队已经选择 ...

  4. Go语言核心之美 3.2-slice切片

    Slice(切片)是长度可变的元素序列(与之相应,上一节中的数组是不可变的),每一个元素都有同样的类型.slice类型写作[]T.T是元素类型.slice和数组写法非常像,差别在于slice没有指定长 ...

  5. Java对话框总结

    总结起来非常easy: 1,对话框类型:消息.确认,选项.输入 2,选择图标:错误,信息.警告.问题,无或者自己定义 3,选择消息:字符串,图标.自己定义组件或者他们的集合 4.对于确认对话框,选择选 ...

  6. 使用adb在电脑和手机间传文件

    首先须要root手机. 然后,"Win + R",打开cmd窗体.以下以copy d:\1.txt到/system/文件夹为例说明. adb push source(localpa ...

  7. NDK开发,没有你想象的那么难

    NDK:Native Development Kit原生开发工具 NDK能干什么:NDK使得在android中,java能够调用C函数库. 为什么要用NDK:我们都知道.java是半解释型语言,非常e ...

  8. HNOI模拟 Day3.22

    第一题: 盾盾的打字机 (drdrd) [题目描述] 盾盾有一个非常有意思的打字机,现在盾哥要用这台打字机来打出一段文章. 由于有了上次的经验,盾盾预先准备好了一段模板 A 存在了内存中,并以此为基础 ...

  9. ramfs、rootfs和initramfs【转】

    ramfs, rootfs and initramfs October 17, 2005 Rob Landley <rob@landley.net> =================== ...

  10. 内容原发网站seo不重视2个标签,导致seo效果不如转发网站

    采集数据,挖掘观点,小心求证,得出结论 时间经过 今日凌晨,爬虫热点采集,其中第一财经是目标站之一,采集到了 http://www.yicai.com/news/5391233.html 谷歌去年悄然 ...