C/C++线程详解

发布于:2025-05-01 ⋅ 阅读:(25) ⋅ 点赞:(0)

一、C语言线程创建(POSIX线程)

1. 基本创建方法

POSIX线程(pthread)是C语言中创建线程的标准API:

#include <pthread.h>
#include <stdio.h>

void* thread_func(void* arg) {
    printf("Thread running with arg: %d\n", *(int*)arg);
    return NULL;
}

int main() {
    pthread_t tid;
    int arg = 42;
    
    // 创建线程
    int ret = pthread_create(&tid, NULL, thread_func, &arg);
    if (ret != 0) {
        perror("pthread_create failed");
        return 1;
    }
    
    // 等待线程结束
    pthread_join(tid, NULL);
    return 0;
}

2. 关键参数说明

  • pthread_t *thread:存储线程ID的指针
  • const pthread_attr_t *attr:线程属性(NULL表示默认)
  • void *(*start_routine)(void*):线程函数指针
  • void *arg:传递给线程函数的参数

3. 线程属性设置

pthread_attr_t attr;
pthread_attr_init(&attr);  // 初始化属性
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 设置分离属性
pthread_create(&tid, &attr, thread_func, NULL);
pthread_attr_destroy(&attr); // 销毁属性对象

二、C++线程创建(std::thread)

1. 基本创建方法

C++11引入了std::thread类简化线程创建:

#include <iostream>
#include <thread>

void thread_function() {
    std::cout << "Thread function executing" << std::endl;
}

int main() {
    // 创建并启动线程
    std::thread t(thread_function);
    
    // 等待线程结束
    t.join();
    return 0;
}

2. 多种创建方式

(1) 使用函数指针
void print_message(const std::string& msg) {
    std::cout << msg << std::endl;
}

std::thread t1(print_message, "Hello from thread");
(2) 使用Lambda表达式
std::thread t2(‌:ml-search[]{
    std::cout << "Lambda thread running" << std::endl;
});

 

(3) 使用成员函数

class MyClass {
public:
    void member_func() {
        std::cout << "Member function thread" << std::endl;
    }
};

MyClass obj;
std::thread t3(&MyClass::member_func, &obj);

3. 线程管理

  • join():等待线程结束
  • detach():分离线程(后台运行)
  • joinable():检查线程是否可join

三、C与C++线程创建对比

特性 std::thread (C++11) pthread (POSIX)
标准化程度 C++标准库的一部分 POSIX标准,非C++原生
跨平台性 所有支持C++11的平台 主要类UNIX系统
接口风格 面向对象(类+成员函数) C风格函数接口
线程创建 构造函数直接启动线程 需显式调用pthread_create
参数传递 类型安全,支持任意可调用对象 需通过void*指针强制转换
资源管理 RAII自动管理(析构自动处理) 需手动调用pthread_join/detach
错误处理 异常机制 返回值错误码
头文件 <thread> <pthread.h>
编译要求 需支持C++11 需链接-lpthread

四、实际应用示例

1. 多线程计算(C++)

#include <iostream>
#include <thread>
#include <vector>

void compute(int start, int end, int& result) {
    int sum = 0;
    for (int i = start; i <= end; ++i) {
        sum += i;
    }
    result = sum;
}

int main() {
    const int n = 1000;
    int result1, result2;
    
    std::thread t1(compute, 1, n/2, std::ref(result1));
    std::thread t2(compute, n/2+1, n, std::ref(result2));
    
    t1.join();
    t2.join();
    
    std::cout << "Total sum: " << result1 + result2 << std::endl;
    return 0;
}

2. 线程池基础(C)

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define THREAD_COUNT 4

void* worker(void* arg) {
    int id = *(int*)arg;
    printf("Worker %d started\n", id);
    // 实际工作任务...
    printf("Worker %d finished\n", id);
    return NULL;
}

int main() {
    pthread_t threads[THREAD_COUNT];
    int thread_ids[THREAD_COUNT];
    
    for (int i = 0; i < THREAD_COUNT; ++i) {
        thread_ids[i] = i;
        pthread_create(&threads[i], NULL, worker, &thread_ids[i]);
    }
    
    for (int i = 0; i < THREAD_COUNT; ++i) {
        pthread_join(threads[i], NULL);
    }
    
    return 0;
}

五、注意事项

  1. 资源管理‌:C++的std::thread使用RAII,析构时若未join/detach会terminate
  2. 参数生命周期‌:确保线程参数在线程使用期间有效
  3. 线程安全‌:共享数据需要同步机制(mutex等)
  4. 错误处理‌:C++使用异常,C检查返回值
  5. 平台差异‌:pthread在不同Unix-like系统实现可能不同

六、使用建议

  1. 优先使用std::thread的情况‌:

    • 开发跨平台应用
    • 需要与C++其他特性(如lambda、智能指针)集成
    • 希望简化资源管理
    • 项目已使用C++11或更高标准
  2. 可能需要使用pthread的情况‌:

    • 维护遗留代码
    • 需要特定POSIX线程特性(如优先级控制)
    • 在仅支持C的嵌入式环境中开发
    • 需要精细控制线程属性(虽然C++11也可通过native_handle实现)

七、性能注意事项

  1. 在主流平台上,两者性能差异通常小于%5,因为:

    • std::thread在Linux上实质是pthread的封装
    • 线程创建/切换等核心操作最终都调用相同的系统API
  2. 实际选择应更多考虑:

    • 代码可维护性
    • 与现有代码库的整合度
    • 团队熟悉程度
    • 长期维护成本

网站公告

今日签到

点亮在社区的每一天
去签到