windows编程: 锁

125 阅读2分钟

前言

在 Windows 编程中,可以使用多种方式创建和管理锁,以实现线程同步,常见的有:

  • 临界区(CRITICAL_SECTION)
  • 互斥锁(Mutex)
  • 信号量(Semaphore)

临界区(Critical Section)

临界区是一种轻量级的同步机制,用于保护共享资源,确保同一时刻只有一个线程可以访问该资源。 作用域是同进程的线程中,实现访问控制.

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

CRITICAL_SECTION cs; // 定义临界区对象

DWORD WINAPI ThreadFunc(LPVOID lpParam) {
    EnterCriticalSection(&cs); // 进入临界区,获取锁
    // 访问共享资源
    std::cout << "Thread " << GetCurrentThreadId() << " is in the critical section." << std::endl;
    LeaveCriticalSection(&cs); // 离开临界区,释放锁
    return 0;
}

int main() {
    InitializeCriticalSection(&cs); // 初始化临界区

    HANDLE threads[2]; // 创建线程句柄数组
    for (int i = 0; i < 2; ++i) {
        threads[i] = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL); // 创建线程
    }

    WaitForMultipleObjects(2, threads, TRUE, INFINITE); // 等待所有线程结束

    for (int i = 0; i < 2; ++i) {
        CloseHandle(threads[i]); // 关闭线程句柄
    }

    DeleteCriticalSection(&cs); // 删除临界区
    return 0;
}

互斥锁(Mutex)

互斥锁是一种用于保护共享资源的同步机制,确保同一时刻只有一个线程可以访问该资源。与临界区不同,互斥锁可以用于跨进程同步。

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

HANDLE hMutex; // 定义互斥锁句柄

DWORD WINAPI ThreadFunc(LPVOID lpParam) {
    WaitForSingleObject(hMutex, INFINITE); // 请求互斥锁
    // 访问共享资源
    std::cout << "Thread " << GetCurrentThreadId() << " is accessing the mutex." << std::endl;
    ReleaseMutex(hMutex); // 释放互斥锁
    return 0;
}

int main() {
    hMutex = CreateMutex(NULL, FALSE, NULL); // 创建互斥锁

    HANDLE threads[2]; // 创建线程句柄数组
    for (int i = 0; i < 2; ++i) {
        threads[i] = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL); // 创建线程
    }

    WaitForMultipleObjects(2, threads, TRUE, INFINITE); // 等待所有线程结束

    for (int i = 0; i < 2; ++i) {
        CloseHandle(threads[i]); // 关闭线程句柄
    }

    CloseHandle(hMutex); // 关闭互斥锁句柄
    return 0;
}

信号量(Semaphore)

信号量是一种更灵活的同步机制,用于控制对共享资源的访问。它可以允许多个线程同时访问资源,适用于需要限制访问数量的场景。

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

HANDLE hSemaphore; // 定义信号量句柄

DWORD WINAPI ThreadFunc(LPVOID lpParam) {
    WaitForSingleObject(hSemaphore, INFINITE); // 请求信号量
    // 访问共享资源
    std::cout << "Thread " << GetCurrentThreadId() << " is accessing the semaphore." << std::endl;
    Sleep(1000); // 模拟操作
    ReleaseSemaphore(hSemaphore, 1, NULL); // 释放信号量
    return 0;
}

int main() {
    hSemaphore = CreateSemaphore(NULL, 2, 2, NULL); // 创建信号量,初始计数和最大计数均为 2

    HANDLE threads[4]; // 创建线程句柄数组
    for (int i = 0; i < 4; ++i) {
        threads[i] = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL); // 创建线程
    }

    WaitForMultipleObjects(4, threads, TRUE, INFINITE); // 等待所有线程结束

    for (int i = 0; i < 4; ++i) {
        CloseHandle(threads[i]); // 关闭线程句柄
    }

    CloseHandle(hSemaphore); // 关闭信号量句柄
    return 0;
}