ToB企服应用市场:ToB评测及商务社交产业平台

标题: C++:pthread线程分离和线程属性 [打印本页]

作者: 吴旭华    时间: 6 天前
标题: C++:pthread线程分离和线程属性
在 C++ 的多线程编程中,pthread 库提供了强盛的功能来管理线程。此中,线程分离和线程属性是两个重要的概念,它们对于优化线程的行为和资源管理有着关键作用。
线程分离

1.1 什么是线程分离

在 pthread 库中,线程有两种状态:可联合(joinable)和分离(detached)。默认情况下,新创建的线程是可联合的。可联合的线程在结束时,需要其他线程调用pthread_join函数来回收其资源,否则会造成资源泄漏。而分离的线程则会在结束时自动释放资源,无需其他线程来回收。
1.2 为什么要使用线程分离

在某些场景下,我们创建的线程执行完使命后,不需要获取其返回值,也不需要关心它的结束状态,此时将线程设置为分离状态可以制止资源浪费和不必要的同步开销。例如,在一个服务器程序中,为每个客户端连接创建一个线程来处理请求,这些线程处理完请求后就可以自动释放资源,不需要主线程逐个等待它们结束。
1.3 如何实现线程分离

在 pthread 库中,可以使用pthread_detach函数来将一个线程设置为分离状态。该函数的原型如下:
  1. int pthread_detach(pthread_t thread);
复制代码
thread是要设置为分离状态的线程标识符。
以下是一个简单的 C++ 代码示例,展示了如何创建一个分离的线程:
  1. #include <iostream>
  2. #include <pthread.h>
  3. #include <unistd.h>
  4. // 线程函数
  5. void* thread_function(void* arg) {
  6.     sleep(2);
  7.     std::cout << "This is a detached thread." << std::endl;
  8.     return nullptr;
  9. }
  10. int main() {
  11.     pthread_t thread;
  12.     // 创建线程
  13.     if (pthread_create(&thread, nullptr, thread_function, nullptr)!= 0) {
  14.         std::cerr << "Failed to create thread" << std::endl;
  15.         return 1;
  16.     }
  17.     // 将线程设置为分离状态
  18.     if (pthread_detach(thread)!= 0) {
  19.         std::cerr << "Failed to detach thread" << std::endl;
  20.         return 1;
  21.     }
  22.     std::cout << "Detached thread created successfully." << std::endl;
  23.     // 主线程继续执行其他任务
  24.     sleep(3);
  25.     return 0;
  26. }
复制代码
创建了一个线程,并使用pthread_detach将其设置为分离状态。主线程在创建和分离线程后,继续执行其他使命,而分离的线程在完成使命后会自动释放资源,其他线程不能再使用 pthread_join 来等待它结束。
pthread_detach 可以在主函数调用,也可以在thread_function函数调用
  1. #include <iostream>
  2. #include <pthread.h>
  3. #include <unistd.h>
  4. using namespace std;
  5. int j = 2;
  6. void* pthread_fun(void *arg)
  7. {
  8.    
  9.     //自己设置为detached状态
  10.     int ret = pthread_detach(pthread_self());
  11.     while(j--)
  12.     {
  13.         cout << " in pthread_task" << endl;
  14.         cout << *(int*)arg << endl;
  15.         sleep(1);
  16.     }
  17.     // 线程返回一个整数值
  18.     int* result = new int(42);
  19.     return static_cast<void*>(result);//pthread_exit(reinterpret_cast<void*>(result));
  20. }
  21. int main()
  22. {
  23.     int ret = 0;
  24.     pthread_t tid = 0;
  25.     int argsend = 99;
  26.     int i = 3;
  27.     ret  = pthread_create(&tid, NULL, pthread_fun, &argsend);
  28.     if(ret != 0)
  29.     {
  30.         cout << " pthread_create error" << endl;
  31.         return -1;
  32.     }
  33.     while(i--)
  34.     {
  35.         cout << "pthread _create success" << endl;
  36.         sleep(2);
  37.     }
  38.    
  39.     return 0;
  40. }
复制代码
线程属性

2.1 线程属性概述

线程属性定义了线程的一些特性,如栈大小、调理计谋、优先级等。通过设置线程属性,可以根据具体的应用需求来优化线程的行为。在 pthread 库中,使用pthread_attr_t类型来表示线程属性。
2.2 常见的线程属性

栈大小:线程的栈用于存储局部变量、函数调用信息等。可以通过pthread_attr_setstacksize函数来设置线程的栈大小。
  1. pthread_attr_t attr;
  2. pthread_attr_init(&attr);
  3. size_t stack_size = 1024 * 1024; // 1MB栈大小
  4. pthread_attr_setstacksize(&attr, stack_size);
复制代码
调理计谋:pthread 库支持多种调理计谋,如 SCHED_OTHER(普通调理计谋)、SCHED_FIFO(先进先出调理计谋)、SCHED_RR(时间片轮转调理计谋)。可以使用pthread_attr_setschedpolicy函数来设置调理计谋。
  1. pthread_attr_t attr;
  2. pthread_attr_init(&attr);
  3. pthread_attr_setschedpolicy(&attr, SCHED_RR);
复制代码
优先级:线程的优先级决定了它在 CPU 竞争中的优先级。可以通过pthread_attr_setschedparam函数来设置线程的优先级。
  1. pthread_attr_t attr;
  2. pthread_attr_init(&attr);
  3. struct sched_param param;
  4. param.sched_priority = 50; // 设置优先级
  5. pthread_attr_setschedparam(&attr, &param);
复制代码
2.3 使用线程属性创建线程

在创建线程时,可以将设置好的线程属性作为参数传递给pthread_create函数。
  1. #include <iostream>
  2. #include <pthread.h>
  3. #include <unistd.h>
  4. // 线程函数
  5. void* thread_function(void* arg) {
  6.     std::cout << "Thread is running." << std::endl;
  7.     return nullptr;
  8. }
  9. int main() {
  10.     pthread_t thread;
  11.     pthread_attr_t attr;
  12.     // 初始化线程属性
  13.     pthread_attr_init(&attr);
  14.     // 设置栈大小为2MB
  15.     size_t stack_size = 2 * 1024 * 1024;
  16.     pthread_attr_setstacksize(&attr, stack_size);
  17.     // 设置调度策略为时间片轮转
  18.     pthread_attr_setschedpolicy(&attr, SCHED_RR);
  19.     // 设置优先级
  20.     struct sched_param param;
  21.     param.sched_priority = 50;
  22.     pthread_attr_setschedparam(&attr, &param);
  23.     // 使用设置好的属性创建线程
  24.     if (pthread_create(&thread, &attr, thread_function, nullptr)!= 0) {
  25.         std::cerr << "Failed to create thread" << std::endl;
  26.         return 1;
  27.     }
  28.     // 等待线程结束
  29.     if (pthread_join(thread, nullptr)!= 0) {
  30.         std::cerr << "Failed to join thread" << std::endl;
  31.         return 1;
  32.     }
  33.     // 销毁线程属性
  34.     pthread_attr_destroy(&attr);
  35.     return 0;
  36. }
复制代码
首先初始化了线程属性,然后设置了栈大小、调理计谋和优先级,末了使用这些属性创建了一个线程


  1. #include <iostream>
  2. #include <pthread.h>
  3. #include <unistd.h>
  4. using namespace std;
  5. int j = 2;
  6. void* pthread_fun(void *arg)
  7. {
  8.    
  9.     //自己设置为detached状态
  10.     //int ret = pthread_detach(pthread_self());
  11.     while(j--)
  12.     {
  13.         cout << " in pthread_task" << endl;
  14.         cout << *(int*)arg << endl;
  15.         sleep(1);
  16.     }
  17.     // 线程返回一个整数值
  18.     int* result = new int(42);
  19.     return static_cast<void*>(result);//pthread_exit(reinterpret_cast<void*>(result));
  20. }
  21. int main()
  22. {
  23.     int ret = 0;
  24.     pthread_t tid = 0;
  25.     int argsend = 99;
  26.     int i = 3;
  27.     pthread_attr_t attr;
  28.     // 初始化线程属性
  29.     pthread_attr_init(&attr);
  30.     ret  = pthread_create(&tid, NULL, pthread_fun, &argsend);
  31.     if(ret != 0)
  32.     {
  33.         cout << " pthread_create error" << endl;
  34.         return -1;
  35.     }
  36.     sched_param param;
  37.     // 获取线程属性中的调度参数
  38.     if (pthread_attr_getschedparam(&attr, &param) != 0) {
  39.         std::cerr << "Failed to get scheduling parameters." << std::endl;
  40.         return 1;
  41.     }
  42.     // 打印调度参数中的优先级
  43.     std::cout << "Scheduling priority: " << param.sched_priority << std::endl;
  44.     // 设置线程属性的分离状态为分离
  45.     ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  46.     if (ret != 0) {
  47.         cerr << "Failed to set detach state." << endl;
  48.         return -1;
  49.     }
  50.     while(i--)
  51.     {
  52.         cout << "pthread _create success" << endl;
  53.         sleep(2);
  54.     }
  55.     int detachstate;
  56.     // 获取线程属性的分离状态
  57.     if (pthread_attr_getdetachstate(&attr, &detachstate) != 0) {
  58.         std::cerr << "Failed to get detach state." << std::endl;
  59.         // 销毁线程属性对象
  60.         pthread_attr_destroy(&attr);
  61.         return 1;
  62.     }
  63.     // 根据分离状态输出相应信息
  64.     if (detachstate == PTHREAD_CREATE_JOINABLE) {
  65.         std::cout << "Thread is joinable." << std::endl;
  66.     } else if (detachstate == PTHREAD_CREATE_DETACHED) {
  67.         std::cout << "Thread is detached." << std::endl;
  68.     } else {
  69.         std::cout << "Unknown detach state." << std::endl;
  70.     }
  71.     // 销毁线程属性
  72.     pthread_attr_destroy(&attr);
  73.     return 0;
  74. }
复制代码
pthread_attr_getdetachstate(&attr, &detachstate) 用于获取线程属性对象 attr 中设置的分离状态。它查询的是线程属性对象的配置信息,而不是pthread_detach线程现实运行时的分离状态。
线程分离和线程属性是 pthread 库中非常实用的功能。通过公道使用线程分离,可以制止资源浪费和同步开销;而机动设置线程属性,则可以根据应用需求优化线程的行为。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4