当前位置: 首页 > news >正文

【Linux系统编程】第四十三弹---多线程编程指南:线程终止方式与C++11中的thread

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】

目录

1、线程终止

1.1、pthread_exit() 

1.2、pthread_cancel() 

1.3、pthread_detach() 

2、C++11中thread 


1、线程终止

问题7 : 新线程如何终止?

1、线程函数 return 

2、pthread_exit 

3、main thread call pthread_cancel ,新线程退出结果是-1 

上一弹已经演示了使用函数return终止进程的方式,此处就只介绍后两种方式了!

可不可以使用我们前面学习过的exit函数终止线程呢?

答案是不能,exit是专门用来终止进程的!

const int num = 10;void *threadrun(void *args)
{std::string name = static_cast<const char *>(args);while (true){std::cout << name << " is running" << std::endl;sleep(1);break; // 1秒后退出循环}exit(1); // 进程: 专门用来终止进程的,不能终止线程
}// main函数结束: main thread 结束,表示进程结束!
int main()
{std::vector<pthread_t> tids;for (int i = 0; i < num; i++){// 1.有线程的idpthread_t tid;// 2.有线程的名字(正确示范)char* name  = new char[128];snprintf(name, 128, "thread-%d", i + 1);pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);// 3.保存所有线程的id信息tids.emplace_back(tid);}for(auto tid : tids){void* name = nullptr;pthread_join(tid,&name);std::cout << (const char*)name << " quit" << std::endl;delete (const char*)name;}// 主线程不退sleep(100);return 0;
}

1.1、pthread_exit() 

pthread_exit()

pthread_exit - 退出一个线程#include <pthread.h>void pthread_exit(void *retval);

参数:

  • retval:这是一个指向返回值的指针,该返回值可以被其他线程通过 pthread_join 函数获取。如果线程不需要返回任何值,可以将此参数设置为 nullptr。

代码演示

修改上面新线程函数代码即可!

void *threadrun(void *args)
{std::string name = static_cast<const char *>(args);while (true){std::cout << name << " is running" << std::endl;sleep(1);break; // 1秒后退出循环}pthread_exit(args); // 专门终止一个线程的!
}

运行结果 

1.2、pthread_cancel() 

 方式三:pthread_cancel

pthread_cancel()

pthread_cancel - 向指定的线程发送取消请求#include <pthread.h>int pthread_cancel(pthread_t thread);

参数

  • thread:指定需要取消的目标线程的标识符。

返回值

  • 成功时返回 0
  • 失败时返回非零值,并设置相应的错误码。

代码演示

const int num = 10;void *threadrun(void *args)
{std::string name = static_cast<const char *>(args);// 死循环while (true){std::cout << name << " is running" << std::endl;sleep(1);}pthread_exit(args); // 专门终止一个线程的!
}// main函数结束: main thread 结束,表示进程结束!
int main()
{std::vector<pthread_t> tids;for (int i = 0; i < num; i++){// 1.有线程的idpthread_t tid;// 2.有线程的名字(正确示范)char* name  = new char[128];snprintf(name, 128, "thread-%d", i + 1);pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);// 3.保存所有线程的id信息tids.emplace_back(tid);}sleep(3);// join todofor(auto tid : tids){pthread_cancel(tid); // 取消新线程std::cout << "cancel: " << PrintToHex(tid) << std::endl;void* result = nullptr; // 线程被取消线程的退出结果是:-1 #define PTHREAD_CANCELED ((void *) -1)pthread_join(tid,&result);std::cout << (long long int)result << " quit" << std::endl;}// 主线程不退sleep(100);return 0;
}

 运行结果 

问题8: 可不可以不join线程,让它执行完就退出呢?

可以!detach分离

a. 一个线程被创建,默认是joinable的,必须要被join的.

b. 如果一个线程被分离,线程的工作状态分离状态,不需要/不能被join的. 依旧属于进程内部,但是不需要被等待了

1.3、pthread_detach() 

pthread_detach - 将指定的线程设置为分离状态#include <pthread.h>int pthread_detach(pthread_t thread);

参数

  • thread:指定要设置为分离状态的线程的标识符。

返回值

  • 成功时返回 0
  • 失败时返回非零值,并设置相应的错误码。
pthread_self - 获取当前线程的线程标识符#include <pthread.h>pthread_t pthread_self(void);

返回值

pthread_self 函数返回一个 pthread_t 类型的值,该值表示调用线程的线程标识符。这个标识符是一个不透明的数据类型,通常用于在线程管理、线程间通信和同步等操作中标识当前线程。

不分离线程且终止线程

代码演示

const int num = 10;void *threadrun(void *args)
{// pthread_detach(pthread_self());std::string name = static_cast<const char *>(args);while (true){std::cout << name << " is running" << std::endl;sleep(1);break; // 1秒后退出循环}pthread_exit(args); 
}int main()
{std::vector<pthread_t> tids;for (int i = 0; i < num; i++){pthread_t tid;char* name  = new char[128];snprintf(name, 128, "thread-%d", i + 1);pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);tids.emplace_back(tid);}// join todofor(auto tid : tids){void* name = nullptr;int n = pthread_join(tid,&name);std::cout << (const char*)name << " quit...,n: " << n << std::endl;delete (const char*)name;}// 主线程不退sleep(100);return 0;
}

运行结果  

新线程分离自己

代码演示

const int num = 10;void *threadrun(void *args)
{pthread_detach(pthread_self());std::string name = static_cast<const char *>(args);while (true){std::cout << name << " is running" << std::endl;sleep(1);break; }pthread_exit(args); 
}int main()
{std::vector<pthread_t> tids;for (int i = 0; i < num; i++){pthread_t tid;char* name  = new char[128];snprintf(name, 128, "thread-%d", i + 1);pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);tids.emplace_back(tid);}// sleep(1);// join todofor(auto tid : tids){void* result = nullptr;int n = pthread_join(tid,&result);std::cout << (long long int)result << " quit...,n: " << n << std::endl;}// 主线程不退//sleep(100);return 0;
}

运行结果  

主线程分离新线程

代码演示

void *threadrun(void *args)
{std::string name = static_cast<const char *>(args);while (true){std::cout << name << " is running" << std::endl;sleep(1);break; }pthread_exit(args); 
}int main()
{std::vector<pthread_t> tids;for (int i = 0; i < num; i++){pthread_t tid;char* name  = new char[128];snprintf(name, 128, "thread-%d", i + 1);pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);tids.emplace_back(tid);}for(auto tid : tids){pthread_detach(tid);// 主线程分离新线程,前提新线程需要存在}// 分离后无需joinfor(auto tid : tids){void* result = nullptr;int n = pthread_join(tid,&result);std::cout << (long long int)result << " quit...,n: " << n << std::endl;}return 0;
}

 运行结果 

2、C++11中thread 

C++11多线程的本质就是对原生线程库接口的封装。

代码演示 

void threadrun(std::string name,int num)
{while(num){std::cout << name << " num : " << num<< std::endl;num--;sleep(1);}
}int main()
{std::string name = "thread-1";std::thread mythread(threadrun,name,10); // 创建线程while(true){std::cout << "main thhread..." << std::endl;sleep(1);}mythread.join(); // 终止线程return 0;
}

运行结果  


http://www.mrgr.cn/news/68245.html

相关文章:

  • uni-app自定义弹窗
  • 飞书API-获取tenant_access_token
  • 【网络】自定义协议——序列化和反序列化
  • ReactPress系列—Next.js 的动态路由使用介绍
  • 4070显卡只要一毛钱?这个双十一太疯狂了
  • Node.js简介以及安装部署 (基础介绍 一)
  • Vue3+element-plus摘要
  • 全局池化(Global Pooling)
  • css基础:底部固定,导航栏浮动在顶部
  • MyBatis项目的创建和增删查改操作
  • Python中的多线程效率分析
  • metrics
  • 数据库数据恢复—通过拼接数据库碎片恢复 SQL Server 数据库
  • 计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
  • spark-本地模式的配置和简单使用
  • MQTT应用实例:Air780E模组AT指令的实践!
  • vue2 关闭 Uncaught error 的全屏提示
  • LabVIEW实验室液压制动系统
  • 【Unity】ScriptableObject的应用和3D物体跟随鼠标移动:鼠标放置物体在场景中
  • 无惧任天堂的法律威胁:Switch模拟器Ryujinx v1.2.72版发布
  • C#编程基础:静态成员与实例成员的区别及访问方式
  • 27系统日志查看
  • 【含开题报告+项目源码+免费部署】基于SSM的医院挂号住院系统的设计与实现
  • nginx中location模块中的root指令和alias指令区别
  • MQTT从入门到精通之 MQTT 客户端编程
  • LabVIEW程序员在工作中常见的挑战