Windows线程同步【2】临界区

临界区是线程同步的一种实现方式。Windows提供了4个关于临界区的函数(InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection,DeleteCriticalSection),要想使用这些函数,必须先有一个临界区变量,

CRITICAL_SECTION cs;

临界区变量,不能复制,不能移动,也不能读取里面的字段(可以取临界区变量的地址)。总而言之,我们在编写程序时,必须把临界区变量当成一个黑箱,一切对临界区的操作必须通过那4个函数来进行。

在使用临界区之前,必须用InitializeCriticalSection函数将其初始化:

InitializeCriticalSection(&cs);

一个线程可以通过EnterCriticalSection函数来进入一个临界区:

EnterCriticalSection(&cs);

一旦一个线程进入了某个临界区,其他线程便不能进入这个临界区。

一个线程可以通过LeaveCriticalSection函数来离开一个临界区:

LeaveCriticalSection(&cs);

当一个线程离开一个临界区之后,其他线程可以进入这个临界区。

当程序不再需要这个临界区时,别忘记将其销毁。

DeleteCriticalSection(&cs);

用法与示例:

临界区的用法是,如果一个变量(记为x)需要被多个线程共享时,那么可以搞一个临界区。任何一个线程在访问x之前,必须先进入临界区,完成对x的访问后,离开临界区。因为一个临界区在同一时刻只允许一个线程进入,这样就保证了x在同一时刻只能被一个线程访问。

在下面的示例中,n是受临界区保护的变量。

#include <iostream>
#include <windows.h>

CRITICAL_SECTION cs;
int n = 0;

DWORD Thread1(void *)
{
    // 其他代码
    EnterCriticalSection(&cs);
    ++n;
    LeaveCriticalSection(&cs);
    // 其他代码
}

DWORD Thread2(void *)
{
    // 其他代码
    EnterCriticalSection(&cs);
    n = 5;
    LeaveCriticalSection(&cs);
    // 其他代码
}

void main()
{
    InitializeCriticalSection(&cs);
    Sleep(5000);
    DeleteCriticalSection(&cs);
}
时间: 2024-08-05 23:41:44

Windows线程同步【2】临界区的相关文章

Windows线程同步

说到windows线程同步的方法,有循环锁,临界区(关键代码段),内核对象(Event,Semaphore,Mutex).甚至进程,线程handle等等. 说说用法: 临界区和mutex都可以用于控制共享资源的互斥访问,不同点是 临界区是用户级对象,消耗小,速度快,但是不能跨进程.mutex是内核对象速度慢,但是可以跨进程. semaphore可以用来进行资源控制,信号量的两个关键参数,现有资源数和最大资源数,可以用于对资源的控制,通过ReleaseSemaphore对资源增加,WaitFor*

Windows线程同步总结

Windows线程同步 Windows的线程同步可以利用互斥对象来实现,也可以使用事件对象,关键代码段来实现. 1 事件对象实现线程同步 <1>Event对象创建函数 事件对象的创建事件对象属于内核对象,它包含以三个成员:使用计数,是否是自动重置还是人工重置的布尔值,通知状态的布尔值. HANDLE CreateEvent( LPSECURITY_ATTRIBUTESlpEventAttributes, BOOLbManualReset, BOOLbInitialState, LPCSTRlp

win32多线程 (二)线程同步之临界区 (critical sections)

所谓critical sections 意指一小块“用来处理一份被共享之资源”的程序代码.你可能必须在程序的许多地方处理这一块可共享的资源.所有这些程序代码可以被同一个critical  section 保护起来.为了阻止问题发生,一次只能有一个线程获准进入critical  section 中.critical section 并不是核心对象.使用方法: CRITICAL_SECTION g_section; 1:初始化 InitializeCriticalSection(&g_section

windows线程同步之原子锁(原子访问)

原子锁(原子访问):一个线程在访问某个资源的同时必须确保其他线程不会同时访问此资源. 没有实现原子锁的结果: //定义一个全局变量 long g_lx = 0; DWORD WINAPI ThreadFunc1(PVOID pvParam){ for( int index=0; index<10000; index++ ) { g_lx++: //g_lx加1: } return 0: } DWORD WINAPI ThreadFunc2(PVOID pvParam){ for( int ind

线程同步之临界区

临界区:当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件.导致竞态条件发生的代码区称作临界区.临界区线程同步适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率比较高. 在.Net中有Monitor.Lock等方式是以临界区的方式来实现线程同步的,我们看一下两者的具体示例. 1.Lock  Lock关键字将代码块标记为临界区,方法是获取指定对象的互斥锁,执行语句,然后释放锁,这样其它线程就可以接着获取锁来进入临界区. Lock关键字保

Windows线程同步(未完)

先介绍一个创建线程的API,参考:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx Creates a thread to execute within the virtual address space of the calling process. HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThr

windows 线程同步学习测试-1

环境win7旗舰64位系统,vs2013,AMD fx™4100 Auad-core processor ,8G内存, 看<windows核心编程>线程同步一章,看到有说g_x++会不同步的问题,试着写些代码加深印象.发现+1太快了,看不出效果,于是for循环了1亿次.代码如下: #include "stdafx.h" using std::cout; using std::endl; using std::cin; unsigned __stdcall ThreadFun

windows 线程同步

Windows 临界区,内核事件,互斥量,信号量. 临界区,内核事件,互斥量,信号量,都能完成线程的同步,在这里把他们各自的函数调用,结构定义,以及适用情况做一个总结. 临界区: 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率比较高. 相关结构:CRITICAL_SECTION  _critical 相关方法: /*初始化,最先调用的函数.没什么好说的,一般windows编程都有类似初始化的方法*/ InitializeCriticalSectio

VC++线程同步(三) 临界区使用例子

临界区(Crtical Section)同步对象 用户模式下的同步对象 Win32中,最容易使用的一个同步机制就是(关键段)Critical Section, 某些共享资源具有互斥性,也就是它要求被互斥地使用,他也是用于资源的互斥, 在大部分情况下,使用临界区替换Mutex(Mutex是内核模式下的同步对象). 局限性:他只能用于同步单个进程中的线程. 在任何同步机制当中,无论是哪个操作系统下,都不要 长时间的锁住资源,如果一直锁定资源,就会一致阻止其他线程的执行, 使整个程序,处于完全停止的状