第二部分:用户区同步

同步和互斥

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

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

多线程产生的问题

#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. [Canvas画图] 藏图阁(16) 人体穴位

    本节目标: 趁着今天是愚人节.阿伟决定来重温一下学医的那段日子. 有那么一段时间, 阿伟对武侠小说和医学同一时候产生了浓厚的兴趣,当时最想学的就是葵花点穴手, 一阳指之类的点穴功夫.轻轻一点.就能把别 ...

  2. 通过uri呼起本地app

    1.在Android本地app清单文件里配置 <activity android:name="com.mdj.ui.WelcomeActivity" android:scre ...

  3. 树状数组 LA 4329 亚洲赛北京赛区题

    复习下树状数组 还是蛮有意思的一道题: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&cat ...

  4. 一些Razor语法

    Layout asp.net mvc中的一些子视图忽然不行了,点击主视图后发现没有弹出来. 通过浏览器调试,发现打开子视图时,加载了大量的JS,CSS等.真奇怪啊,这些都是在主视图加载的啊,怎么子视图 ...

  5. 【bzoj3609】[Heoi2014]人人尽说江南好

    可以算出合并多少次. #include<algorithm> #include<iostream> #include<cstdlib> #include<cs ...

  6. 使用qemu

    1 获取qemu启动linux kernel的log qemu-system-x86_64 -nographic -kernel xxx -initrd xxx -append "conso ...

  7. 修改ip 在linux上永久修改IP地址 子网掩码

    小结: 1. 子网掩码.子网IP计算 2. linux centos 修改ip地址细节介绍_LINUX_操作系统_脚本之家 http://www.jb51.net/LINUXjishu/66509.h ...

  8. vijos - P1077克隆龙 (找规律 + 指数型母函数 + python)

    P1077克隆龙 Accepted 标签:[显示标签] 描写叙述 如今龙的克隆已成为可能,龙基因由ACTG字母组成,而龙的基因有例如以下特点: 1.A在基因中的出现为偶数次(包含0): 2.C的情况也 ...

  9. ngnix 详解

    4 Nginx的rpm软件包安装 4.1 安装包在位置 D:\讲课内容--\新巴巴运动网\nginx高并发解决\nginx安装包 4.2 此种安装方式不用安装gcc等编译工具 4.3 安装命令如下 r ...

  10. JLabel作为展现元素时需要注意的事项

    如果没有内容,JLabel默认透明就无法作为点击区域了,所以为了让其可以响应鼠标事件需要设置 setOpaque(true) 这样就可以响应鼠标事件了 (吐槽一下,多年以前在大学做个web地图导航的网 ...