跳转至

线程管理API

概述

线程是进程中的执行单元,同一进程的所有线程共享进程的地址空间和资源。Windows提供了完整的线程管理API。

线程创建

CreateThread - 创建线程

CreateThread函数

创建一个在调用进程的虚拟地址空间内执行的线程。

C++
1
2
3
4
5
6
7
8
HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全属性
    SIZE_T                dwStackSize,        // 栈大小
    LPTHREAD_START_ROUTINE lpStartAddress,    // 线程函数
    LPVOID                lpParameter,        // 传递参数
    DWORD                 dwCreationFlags,    // 创建标志
    LPDWORD               lpThreadId          // 线程ID
);

参数: - lpThreadAttributes:安全属性,NULL表示默认 - dwStackSize:栈大小,0表示默认 - lpStartAddress:线程函数指针 - lpParameter:传递给线程函数的参数 - dwCreationFlags: - 0:立即运行 - CREATE_SUSPENDED:创建后挂起 - lpThreadId:接收线程ID

线程函数原型

C++
DWORD WINAPI ThreadFunction(LPVOID lpParameter);

示例

C++
#include <windows.h>
#include <stdio.h>

// 线程函数
DWORD WINAPI MyThread(LPVOID param) {
    int* pValue = (int*)param;
    for (int i = 0; i < 5; i++) {
        printf("Thread: %d, Value: %d\n", GetCurrentThreadId(), *pValue);
        Sleep(1000);
    }
    return 0;
}

int main() {
    int value = 100;
    
    // 创建线程
    DWORD threadId;
    HANDLE hThread = CreateThread(
        NULL,           // 默认安全属性
        0,              // 默认栈大小
        MyThread,       // 线程函数
        &value,         // 参数
        0,              // 立即运行
        &threadId       // 线程ID
    );
    
    if (hThread == NULL) {
        printf("CreateThread failed: %d\n", GetLastError());
        return -1;
    }
    
    printf("Created thread: %d\n", threadId);
    
    // 等待线程结束
    WaitForSingleObject(hThread, INFINITE);
    
    // 关闭线程句柄
    CloseHandle(hThread);
    
    return 0;
}

_beginthreadex - C运行时线程创建

推荐使用

使用C运行时库的线程函数更安全,可以正确初始化C运行时环境。

C++
1
2
3
4
5
6
7
8
uintptr_t _beginthreadex(
    void *security,
    unsigned stack_size,
    unsigned ( *start_address )( void * ),
    void *arglist,
    unsigned initflag,
    unsigned *thrdaddr
);

示例

C++
#include <process.h>
#include <stdio.h>

unsigned WINAPI MyThread(void* param) {
    printf("Thread running\n");
    return 0;
}

int main() {
    unsigned threadId;
    HANDLE hThread = (HANDLE)_beginthreadex(
        NULL, 0, MyThread, NULL, 0, &threadId
    );
    
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    
    return 0;
}

线程控制

OpenThread - 打开线程

C++
1
2
3
4
5
HANDLE OpenThread(
    DWORD dwDesiredAccess, // 访问权限
    BOOL  bInheritHandle,  // 继承标志
    DWORD dwThreadId       // 线程ID
);

访问权限: - THREAD_ALL_ACCESS - THREAD_TERMINATE - THREAD_SUSPEND_RESUME - THREAD_GET_CONTEXT - THREAD_SET_CONTEXT - THREAD_QUERY_INFORMATION

SuspendThread - 挂起线程

C++
1
2
3
DWORD SuspendThread(
    HANDLE hThread
);

返回值:之前的挂起计数

ResumeThread - 恢复线程

C++
1
2
3
DWORD ResumeThread(
    HANDLE hThread
);

示例

C++
1
2
3
4
5
6
7
// 创建挂起的线程
HANDLE hThread = CreateThread(NULL, 0, MyThread, NULL, CREATE_SUSPENDED, NULL);

// 做一些初始化工作...

// 恢复线程
ResumeThread(hThread);

TerminateThread - 终止线程

TerminateThread函数

强制终止线程,非常危险,可能导致资源泄漏、死锁等问题。

C++
1
2
3
4
BOOL TerminateThread(
    HANDLE hThread,  // 线程句柄
    DWORD  dwExitCode // 退出代码
);

示例

C++
// 不推荐使用!
TerminateThread(hThread, 1);

ExitThread - 退出当前线程

C++
1
2
3
VOID ExitThread(
    DWORD dwExitCode
);

示例

C++
1
2
3
4
5
6
7
DWORD WINAPI MyThread(LPVOID param) {
    // 线程工作...
    if (error) {
        ExitThread(1);  // 错误退出
    }
    return 0;  // 正常退出
}

线程信息

GetCurrentThread - 获取当前线程句柄

C++
HANDLE GetCurrentThread();

GetCurrentThreadId - 获取当前线程ID

C++
DWORD GetCurrentThreadId();

示例

C++
printf("Current thread ID: %d\n", GetCurrentThreadId());

GetThreadId - 从句柄获取线程ID

C++
1
2
3
DWORD GetThreadId(
    HANDLE Thread
);

GetExitCodeThread - 获取线程退出码

C++
1
2
3
4
BOOL GetExitCodeThread(
    HANDLE  hThread,
    LPDWORD lpExitCode
);

线程优先级

GetThreadPriority - 获取线程优先级

C++
1
2
3
int GetThreadPriority(
    HANDLE hThread
);

SetThreadPriority - 设置线程优先级

C++
1
2
3
4
BOOL SetThreadPriority(
    HANDLE hThread,
    int    nPriority
);

优先级值

优先级 说明
THREAD_PRIORITY_IDLE -15 空闲
THREAD_PRIORITY_LOWEST -2 最低
THREAD_PRIORITY_BELOW_NORMAL -1 低于标准
THREAD_PRIORITY_NORMAL 0 标准
THREAD_PRIORITY_ABOVE_NORMAL 1 高于标准
THREAD_PRIORITY_HIGHEST 2 最高
THREAD_PRIORITY_TIME_CRITICAL 15 时间关键

示例

C++
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

线程局部存储(TLS)

TlsAlloc - 分配TLS索引

C++
DWORD TlsAlloc();

TlsFree - 释放TLS索引

C++
1
2
3
BOOL TlsFree(
    DWORD dwTlsIndex
);

TlsSetValue - 设置TLS值

C++
1
2
3
4
BOOL TlsSetValue(
    DWORD  dwTlsIndex,
    LPVOID lpTlsValue
);

TlsGetValue - 获取TLS值

C++
1
2
3
LPVOID TlsGetValue(
    DWORD dwTlsIndex
);

示例

C++
#include <windows.h>
#include <stdio.h>

DWORD tlsIndex;

DWORD WINAPI ThreadFunc(LPVOID param) {
    int value = (int)(LONG_PTR)param;
    
    // 设置线程局部存储
    TlsSetValue(tlsIndex, (LPVOID)(LONG_PTR)value);
    
    // 获取线程局部存储
    int stored = (int)(LONG_PTR)TlsGetValue(tlsIndex);
    printf("Thread %d: TLS value = %d\n", GetCurrentThreadId(), stored);
    
    return 0;
}

int main() {
    // 分配TLS索引
    tlsIndex = TlsAlloc();
    
    // 创建多个线程
    HANDLE threads[3];
    for (int i = 0; i < 3; i++) {
        threads[i] = CreateThread(NULL, 0, ThreadFunc, (LPVOID)(LONG_PTR)(i * 100), 0, NULL);
    }
    
    // 等待所有线程
    WaitForMultipleObjects(3, threads, TRUE, INFINITE);
    
    // 释放TLS索引
    TlsFree(tlsIndex);
    
    // 关闭句柄
    for (int i = 0; i < 3; i++) {
        CloseHandle(threads[i]);
    }
    
    return 0;
}

线程池

QueueUserWorkItem - 队列工作项

C++
1
2
3
4
5
BOOL QueueUserWorkItem(
    LPTHREAD_START_ROUTINE Function,
    PVOID                  Context,
    ULONG                  Flags
);

标志: - WT_EXECUTEDEFAULT:默认 - WT_EXECUTEINIOTHREAD:I/O线程 - WT_EXECUTEINPERSISTENTTHREAD:持久线程 - WT_EXECUTELONGFUNCTION:长时间函数

示例

C++
1
2
3
4
5
6
DWORD WINAPI WorkItem(LPVOID param) {
    printf("Work item executed in thread: %d\n", GetCurrentThreadId());
    return 0;
}

QueueUserWorkItem(WorkItem, NULL, WT_EXECUTEDEFAULT);

线程同步对象

CreateMutex - 创建互斥体

C++
1
2
3
4
5
HANDLE CreateMutex(
    LPSECURITY_ATTRIBUTES lpMutexAttributes,
    BOOL                  bInitialOwner,
    LPCTSTR               lpName
);

示例

C++
1
2
3
4
HANDLE hMutex = CreateMutex(NULL, FALSE, L"MyMutex");
WaitForSingleObject(hMutex, INFINITE);
// 临界区代码
ReleaseMutex(hMutex);

ReleaseMutex - 释放互斥体

C++
1
2
3
BOOL ReleaseMutex(
    HANDLE hMutex
);

CreateSemaphore - 创建信号量

C++
1
2
3
4
5
6
HANDLE CreateSemaphore(
    LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
    LONG                  lInitialCount,
    LONG                  lMaximumCount,
    LPCTSTR               lpName
);

ReleaseSemaphore - 释放信号量

C++
1
2
3
4
5
BOOL ReleaseSemaphore(
    HANDLE hSemaphore,
    LONG   lReleaseCount,
    LPLONG lpPreviousCount
);

CreateEvent - 创建事件对象

C++
1
2
3
4
5
6
HANDLE CreateEvent(
    LPSECURITY_ATTRIBUTES lpEventAttributes,
    BOOL                  bManualReset,
    BOOL                  bInitialState,
    LPCTSTR               lpName
);

SetEvent - 设置事件

C++
1
2
3
BOOL SetEvent(
    HANDLE hEvent
);

ResetEvent - 重置事件

C++
1
2
3
BOOL ResetEvent(
    HANDLE hEvent
);

临界区

InitializeCriticalSection - 初始化临界区

C++
1
2
3
void InitializeCriticalSection(
    LPCRITICAL_SECTION lpCriticalSection
);

EnterCriticalSection - 进入临界区

C++
1
2
3
void EnterCriticalSection(
    LPCRITICAL_SECTION lpCriticalSection
);

LeaveCriticalSection - 离开临界区

C++
1
2
3
void LeaveCriticalSection(
    LPCRITICAL_SECTION lpCriticalSection
);

DeleteCriticalSection - 删除临界区

C++
1
2
3
void DeleteCriticalSection(
    LPCRITICAL_SECTION lpCriticalSection
);

示例

C++
#include <windows.h>
#include <stdio.h>

CRITICAL_SECTION cs;
int counter = 0;

DWORD WINAPI ThreadFunc(LPVOID param) {
    for (int i = 0; i < 1000; i++) {
        EnterCriticalSection(&cs);
        counter++;
        LeaveCriticalSection(&cs);
    }
    return 0;
}

int main() {
    InitializeCriticalSection(&cs);
    
    HANDLE threads[10];
    for (int i = 0; i < 10; i++) {
        threads[i] = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
    }
    
    WaitForMultipleObjects(10, threads, TRUE, INFINITE);
    
    printf("Counter: %d\n", counter);
    
    DeleteCriticalSection(&cs);
    
    for (int i = 0; i < 10; i++) {
        CloseHandle(threads[i]);
    }
    
    return 0;
}

实用示例

生产者-消费者模式

C++
#include <windows.h>
#include <stdio.h>
#include <queue>

const int BUFFER_SIZE = 10;
std::queue<int> buffer;

CRITICAL_SECTION cs;
HANDLE hNotEmpty;  // 事件:缓冲区非空
HANDLE hNotFull;   // 事件:缓冲区未满

DWORD WINAPI Producer(LPVOID param) {
    for (int i = 0; i < 20; i++) {
        EnterCriticalSection(&cs);
        
        // 等待缓冲区有空位
        while (buffer.size() >= BUFFER_SIZE) {
            LeaveCriticalSection(&cs);
            WaitForSingleObject(hNotFull, INFINITE);
            EnterCriticalSection(&cs);
        }
        
        // 生产
        buffer.push(i);
        printf("Produced: %d\n", i);
        
        // 发信号:缓冲区非空
        SetEvent(hNotEmpty);
        ResetEvent(hNotFull);
        
        LeaveCriticalSection(&cs);
        Sleep(100);
    }
    return 0;
}

DWORD WINAPI Consumer(LPVOID param) {
    for (int i = 0; i < 20; i++) {
        EnterCriticalSection(&cs);
        
        // 等待缓冲区有数据
        while (buffer.empty()) {
            LeaveCriticalSection(&cs);
            WaitForSingleObject(hNotEmpty, INFINITE);
            EnterCriticalSection(&cs);
        }
        
        // 消费
        int item = buffer.front();
        buffer.pop();
        printf("Consumed: %d\n", item);
        
        // 发信号:缓冲区未满
        SetEvent(hNotFull);
        ResetEvent(hNotEmpty);
        
        LeaveCriticalSection(&cs);
        Sleep(150);
    }
    return 0;
}

int main() {
    InitializeCriticalSection(&cs);
    hNotEmpty = CreateEvent(NULL, TRUE, FALSE, NULL);
    hNotFull = CreateEvent(NULL, TRUE, TRUE, NULL);
    
    HANDLE hProducer = CreateThread(NULL, 0, Producer, NULL, 0, NULL);
    HANDLE hConsumer = CreateThread(NULL, 0, Consumer, NULL, 0, NULL);
    
    WaitForSingleObject(hProducer, INFINITE);
    WaitForSingleObject(hConsumer, INFINITE);
    
    CloseHandle(hProducer);
    CloseHandle(hConsumer);
    CloseHandle(hNotEmpty);
    CloseHandle(hNotFull);
    DeleteCriticalSection(&cs);
    
    return 0;
}

参考资料