【C++】多线程
2026/7/1 6:29:18 网站建设 项目流程

多线程

线程:是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程:是多任务处理的一种特殊形式。

一般情况下,两种类型的多任务处理:基于进程和基于线程

  • 基于进程的多任务处理是程序的并发执行。
  • 基于线程的多任务处理是同一程序的片段的并发执行。
    • 并发:多个任务在时间片段内交替执行,表现出同时进行的效果。
    • 并行:多个任务在多个处理器或处理器核上同时执行。

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; }
  • out
main thread pid=6255 main Self: id=139668265477952 设置线程为可连接状态(JOINABLE) 设置堆栈大小: 262144 bytes 设置调度策略: SCHED_OTHER 设置显式调度继承 设置竞争范围: PTHREAD_SCOPE_SYSTEM Main thread 0 ChildThread: pid=6255 ChildSelf: id=139668265473792
调用普通函数

pthread_create接收的是函数指针,传入普通函数会报错参数类型错误,必须接收

void * ( * )(void * )

采用外面线程包装函数

error: invalid conversion from ‘void (*)()’ to ‘void* (*)(void*)’ [-fpermissive] rc = pthread_create(&thread, &attr, &PrintThread_1, NULL);
void PrintThread_1() { for(int i = 0; i < 100; i++){ cout << i << endl; sleep(1); } return; } void* thread_wrapper(void* arg) { (void)arg; // 忽略参数(防止编译器警告) // 调用真正的无参数函数 PrintThread_1(); return NULL; // 线程返回值 } int result = pthread_create(&thread, &attr, thread_wrapper, NULL);
调用静态函数
static void* PrintThread_2(void* arg) { (void)arg; for(int i = 0; i < 100; i++){ cout << i << endl; sleep(1); } return NULL; } int result = pthread_create(&thread, &attr, PrintThread_2, (void*)param);
调用 类静态函数
#include <pthread.h> #include <iostream> #include <unistd.h> using namespace std; class MyClass { public: // 静态成员函数 - 可以作为线程函数 static void* PrintThread_3(void* arg) { cout << "Static member function called" << endl; for(int i = 0; i < 10; i++){ cout << "fun: " << i << endl; sleep(1); } cout << "Static member function finished" << endl; return nullptr; } }; int main() { pthread_t thread; int param = 42; // 直接调用类的静态成员函数 //pthread_create(&thread, NULL, &MyClass::PrintThread_3,&param); // 通过类名调用静态函数 pthread_create(&thread, NULL, MyClass::PrintThread_3, &param); for(int i = 0; i < 10; i++){ cout << "main:" << i << endl; sleep(1); } pthread_join(thread, nullptr); cout << "Main: Thread completed" << endl; return 0; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询