标签:删除 wait 位置 return 就是 一个 语言 正在执行 i++
同步:就是按照一定的顺序执行不同的线程
互斥:当一个线程访问某一资源的时候,其它线程不能同时访问
#include <stdio.h> #include <windows.h> ? // 全局变量,被不同的线程访问和修改 int g_Number = 0; ? DWORD WINAPI ThreadPro1(LPVOID lpThreadParameter) { // 为 g_Number 自增 100000 次 for (int i = 0; i < 100000; i++) g_Number++; return 0; } DWORD WINAPI ThreadPro2(LPVOID lpThreadParameter) { // 为 g_Number 自增 100000 次 for (int i = 0; i < 100000; i++) g_Number++; return 0; } int main() { // 创建两个线程 HANDLE hThread1 = CreateThread(NULL, NULL, ThreadPro1, NULL, NULL, NULL); HANDLE hThread2 = CreateThread(NULL, NULL, ThreadPro2, NULL, NULL, NULL); ? // 等待两个线程执行结束 WaitForSingleObject(hThread1, -1); WaitForSingleObject(hThread2, -1); ? // 输出修改后的全局变量 printf("%d", g_Number); ? return 0; }
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) -----------
特点:将一条语句转换成了具有同等功能的单条汇编指令 lock inc dword ptr [Number]
缺点:只能给单个整数类型(4/8)进行保护,不能给使一段代码变成原子操作
函数:
InterlockedXXX
for (int i = 0; i < 100000; i++) { // 使用原子操作函数,将自增操作变为不可分割的一条指令 InterlockedIncrement(&g_Number); ? // 以上语句会被翻译成下列单条汇编指令 // lock inc dword ptr [g_Number] }
特点:拥有线程拥有者的概念,同一个线程可以不断的重新进入临界区,但是进入了多少次,就要退出多少。
缺点:一旦拥有临界区的线程崩溃,那么所有等待临界区的线程就会产生死锁。
函数:
初始化: InitializeCriticalSection
保护:EnterCriticalSection
结束保护 :LeaveCriticalSection
删除:DeleteCriticalSection
// 1. 创建一个临界区(关键段)结构体 CRITICAL_SECTION CriticalSection = { 0 }; ? // 2. 在 【main】 函数中对创建的临界区进行初始化操作 // InitializeCriticalSection(&CriticalSection); ? DWORD WINAPI ThreadPro1(LPVOID lpThreadParameter) { // 为 g_Number 自增 100000 次 for (int i = 0; i < 100000; i++) { // 当有一个线程正在执行代码的时候 ? // 同一个线程每进入一次受保护的区域,RecursionCount +1 // OwningThread 当前被哪一个线程所有 ? // 3. 使用 EnterCriticalSection 标识需要保护的代码的起始位置 EnterCriticalSection(&CriticalSection); g_Number++; // 4. 使用 LeaveCriticalSection 标识需要保护的代码的结束位置 LeaveCriticalSection(&CriticalSection); } return 0; }
标签:删除 wait 位置 return 就是 一个 语言 正在执行 i++
原文地址:https://www.cnblogs.com/ltyandy/p/10938192.html