【C++】多线程
·
线程:是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程:是多任务处理的一种特殊形式。
一般情况下,两种类型的多任务处理:基于进程和基于线程。
- 基于进程的多任务处理是程序的并发执行。
- 基于线程的多任务处理是同一程序的片段的并发执行。
- 并发:多个任务在时间片段内交替执行,表现出同时进行的效果。
- 并行:多个任务在多个处理器或处理器核上同时执行。
C++ 多线程编程涉及在一个程序中创建和管理多个并发执行的线程。
实现多线程
在C++ 11 新特性中std::thread对linux中的pthread和windows中的Win32 API进行封装,支持跨平台、移动语义等特点,本文主要使用std::thread,对pthread和Thread简单使用。
使用<windows.h>实现
windows下的原生API进行创建线程。
- 接口
//创建线程
HANDLE CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全属性
_In_ SIZE_T dwStackSize, // 堆栈大小
_In_ LPTHREAD_START_ROUTINE lpStartAddress, // 线程函数地址
_In_opt_ LPVOID lpParameter, // 线程参数
_In_ DWORD dwCreationFlags, // 创建标志
_Out_opt_ LPDWORD lpThreadId // 接收线程ID
);
//关闭句柄
CloseHandle(
_In_ _Post_ptr_invalid_ HANDLE hObject
);
//待线程结束
//等待事件、信号量等同步对象
DWORD WaitForSingleObject(
_In_ HANDLE hHandle, // 要等待的对象句柄
_In_ DWORD dwMilliseconds // 超时时间(毫秒)
);
// 使用标志变量让线程自然退出
// 使用事件对象通知线程退出
BOOL TerminateThread(
_In_ HANDLE hThread, // 要终止的线程句柄
_In_ DWORD dwExitCode // 线程退出码
);
// 检查线程是否仍在运行
// 获取线程的执行结果
// 调试和错误处理
BOOL GetExitCodeThread(
_In_ HANDLE hThread, // 线程句柄
_Out_ LPDWORD lpExitCode // 接收退出码的指针
);
// 设置当前线程属性(优先级、亲和性等)
// 在线程函数中操作自身
HANDLE GetCurrentThread(VOID); // 无参数,返回当前线程伪句柄
- 实现
#include <windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI threadrun(LPVOID lpParamter)
{
for (int i = 0; i < 10; i++) {
cout << "Threadrun:" << i << endl;
Sleep(50);
}
return 0;
}
int main()
{
HANDLE hThread = CreateThread(NULL, 0, threadrun, NULL, 0, NULL);
CloseHandle(hThread); //CloseHandle只是关闭了句柄,并不会终止线程。但是,如果主线程退出,进程会终止,所有线程都会结束。
for (int i = 0; i < 10; i++) {
cout << "Main:" << i << endl;
Sleep(10);
}
//WaitForSingleObject(hThread, INFINITE); //等待线程完成 ,前提是hThread没有关闭
return 0;
}
使用pthread实现
- 接口
// 创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
// 线程退出
void pthread_exit(void *retval);
// 等待线程结束
int pthread_join(pthread_t thread, void **retval);
// 分离线程
int pthread_detach(pthread_t thread);
// 取消线程
int pthread_cancel(pthread_t thread);
// 获取当前线程ID
pthread_t pthread_self(void);
// 比较线程ID
int pthread_equal(pthread_t t1, pthread_t t2);
// 初始化线程属性
int pthread_attr_init(pthread_attr_t *attr);
// 销毁线程属性
int pthread_attr_destroy(pthread_attr_t *attr);
// 设置分离状态
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
// 获取分离状态
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
// 设置堆栈大小
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
// 设置调度策略
/*
* 参数:policy -
* SCHED_FIFO 先进先出
* SCHED_RR 轮转
* SCHED_OTHER 其他(默认)
*/
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
- 实现
#include <pthread.h> // POSIX 线程库头文件
#include <stdio.h> // 标准输入输出头文件
#include <stdlib.h> // 标准库头文件(包含exit等函数)
#include <unistd.h> // Unix标准库头文件,包含getpid(), sleep()等系统调用
#include <iostream> // C++标准输入输出流
#include <cstring>
using namespace std; // 使用std命名空间
// 线程函数 - 子线程的入口点
// 参数:threadid - 传递给线程的参数(这里用作线程标识符)
// 返回值:void* - 线程退出时可以返回一个指针(这里返回NULL)
void *PrintThread(void *threadid)
{
// 获取当前线程ID的方式:
// 使用pthread_self()获取POSIX线程ID(pthread_t类型)
pthread_t id = pthread_self();
pid_t tid = getpid(); // 这获取的是进程ID,不是线程ID
cout << "ChildThread:" << " pid=" << tid << endl; // 这里打印的是进程ID
cout << "ChildSelf:" << " id=" << id << endl;
for(int i = 0; i < 100; i++){
cout << i << endl;
sleep(1); // 休眠1秒,模拟耗时操作
}
// 线程退出
pthread_exit(NULL); // 显式退出线程,参数NULL表示不返回任何值
// 或者直接: return NULL; // 等效的退出方式
}
int main(int argc, char *argv[])
{
// 获取当前进程ID(注意:主线程也在同一个进程中)
pid_t tid = getpid(); // 获取当前进程ID
cout << "main thread" << " pid=" << tid << endl; // 打印主线程所在进程的ID
pthread_t id = pthread_self();
cout << "main Self:" << " id=" << id << endl;
pthread_t thread; // 线程句柄/标识符(用于引用创建的线程)
pthread_attr_t attr; //线程属性对象
int result; // 存储函数返回码(return code)
long param = 1; // 线程参数,这里作为线程ID使用(值为1)
result = pthread_attr_init(&attr); //初始化属性
if (result != 0) {
cerr << "Error: pthread_attr_init failed: " << strerror(result) << endl;
return 0;
}
//设置分离状态 PTHREAD_CREATE_JOINABLE 或 PTHREAD_CREATE_DETACHED
result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if (result == 0) {
cout << "设置线程为可连接状态(JOINABLE)" << endl;
}
// 设置堆栈大小(256KB)
size_t stacksize = 256 * 1024; // 256KB
result = pthread_attr_setstacksize(&attr, stacksize);
if (result == 0) {
size_t actual_stacksize;
pthread_attr_getstacksize(&attr, &actual_stacksize);
cout << "设置堆栈大小: " << actual_stacksize << " bytes" << endl;
}
// 设置调度策略 普通应用用 SCHED_OTHER分时调度
result = pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
if (result == 0) {
cout << "设置调度策略: SCHED_OTHER" << endl;
}
// 设置继承调度属性(使用显式设置而非继承)
result = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (result == 0) {
cout << "设置显式调度继承" << endl;
}
//设置竞争范围(Linux只支持系统级) Linux只支持 PTHREAD_SCOPE_SYSTEM
result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
if (result == 0) {
cout << "设置竞争范围: PTHREAD_SCOPE_SYSTEM" << endl;
}
// 创建新线程
// &thread: 用于存储新线程的标识符
// NULL: 线程属性(使用默认属性)
// PrintThread: 线程函数指针(新线程执行的函数)
// (void *)param: 传递给线程函数的参数(将long转换为void*)
result = pthread_create(&thread, &attr, PrintThread, (void *)param);
// 检查线程创建是否成功
if (result) // rc != 0 表示创建失败
{
// pthread_create返回错误码(非零)
// 通常应该处理错误,这里直接返回
return 0;
}
result = pthread_attr_destroy(&attr);
// 主线程继续执行自己的工作(与子线程并发执行)
for(int i = 0; i < 5; i++){
cout << "Main thread " << i << endl; // 主线程输出
sleep(2); // 休眠2秒(子线程休眠1秒,所以子线程输出更频繁)
}
pthread_join(thread, NULL);
return 0;
}
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)