【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;
}
运行结果