1. 什么是线程
线程是比进程更小的能独立运行的基本单位,线程基本上不拥有系统资源
一个进程下可以开多个线程,这些线程是并发的
查看线程命令
命令 | 含义 |
---|---|
ps -T -p | -T开启线程查看 |
top -H -p | -H开启线程查看 |
文件书写
文件 | 含义 |
---|---|
/proc/{PID}/task/ | 线程默认的名字和进程名相同 |
/proc/{PID}/task/{tid}/comm | 线程名 |
2. 操作
操作 | 函数 |
---|---|
线程标识 | pthread_t pthread_self(void) |
线程创建 | int pthread_create(pthread_t * tidp, pthread_attr_t * attr, void *(*start_rtn)(void), void * arg) |
子线程终止 | void pthread_exit(void* retval) |
线程合并 | int pthread_join(pthread_t tid, void **retval) |
线程分离 | int pthread_detach(pthread_t tid) |
发送信号 | int pthread_kill(pthread_t tid, int sig) |
线程标识 pthread_self()
线程创建 pthread_create(线程id指针 , NULL, 函数指针, 函数参数)
2.1 线程的并发
创建一个线程,让主进程和这个线程并发执行:
#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void* handle(void*){
for(int i=0;i<10;++i){
sleep(1);
cout << pthread_self() << ":" << i << endl;
}
return NULL;
}
int main(){
cout << getpid() << endl; // pid
cout << pthread_self() << endl; // 线程标识
pthread_t tid;
pthread_create(&tid,NULL,handle,NULL); // 创建一个线程,handle传指针并返回指针,是这个线程做的事
// 主进程也做这个
for(int i=0;i<10;++i){
sleep(1);
cout << pthread_self() << ":" << i << endl;
}
}
结果为:
[root@foundation1 C++7.13]# g++ thread.cpp -pthread
[root@foundation1 C++7.13]# ./a.out
7423
140021348697920
140021348697920:0
140021330745088:0
140021330745088140021348697920::11
140021330745088:2
140021348697920:2
140021330745088:3
140021348697920:3
140021330745088140021348697920:4:4
140021348697920140021330745088:5:5
140021348697920:6
140021330745088:6
140021348697920140021330745088:7:7
140021348697920140021330745088::8
8
140021330745088140021348697920::99
可以发现两个是并发的
在另一个窗口看所有线程ps -T -ef
可以发现,两个进程id是一样的,线程id不同
2.2 共用变量
同一个进程中两个线程可以共用全局变量,也可以共用局部变量:
#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void* handle(void* p){
int* pn = (int*)p;
for(int i=0;i<10;++i){
sleep(1);
cout << pthread_self() << ":" << --*pn << endl; // 对n减
}
return NULL;
}
int main(){
cout << getpid() << endl;
cout << pthread_self() << endl;
int n = 5; // 定义局部变量
pthread_t tid;
pthread_create(&tid,NULL,handle,&n); // 这里需要传参
// 主进程
for(int i=0;i<10;++i){
sleep(1);
cout << pthread_self() << ":" << ++n << endl; // 对n加
}
}
结果为:
[root@foundation1 C++7.13]# g++ thread.cpp -pthread
[root@foundation1 C++7.13]# ./a.out
7818
139961303992128
139961303992128139961286039296::4
5
139961286039296139961303992128::45
139961286039296139961303992128::54
139961286039296139961303992128::45
139961303992128139961286039296::56
139961303992128139961286039296::56
139961286039296139961303992128::54
139961303992128139961286039296::56
139961286039296139961303992128::54
139961286039296139961303992128::54
可以发现两个线程对同一个n加减,表明变量是共用的
2.3 线程合并
有时候主进程已经结束了,但子线程还没有跑完,整个程序就结束了
我们可以使用
线程合并 pthread_join( 线程id, 返回值)
让主进程等待子线程跑完
有时变量的生存周期结束后还没有完全释放,使用动态申请内存避免这种情况
#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void* handle(void* p){
int* pn = (int*)p;
for(int i=0;i<10;++i){
sleep(1);
cout << pthread_self() << ":" << --*pn << endl;
}
delete pn; // 到这里再释放
// pthread_exit();
return NULL;
}
// 创建线程
pthread_t test(){
int* p = new int(3); // 从这里申请,初始值为3
pthread_t tid;
pthread_create(&tid,NULL,handle,p);
return tid;
}
int main(){
cout << getpid() << endl;
cout << pthread_self() << endl;
pthread_t tid = test();
int n = 5;
// pthread_detach(tid);
for(int i=0;i<5;++i){
sleep(1);
cout << pthread_self() << ":" << ++n << endl;
}
pthread_join(tid,NULL); // 线程合并
return 0;
}
结果为:
[root@foundation1 C++7.13]# g++ thread3.cpp -pthread
[root@foundation1 C++7.13]# ./a.out
11227
139954324326208
139954324326208139954306373376:2:
6
139954324326208139954306373376:7:1
139954324326208139954306373376:8:0
139954324326208139954306373376::-19
139954306373376:-2
139954324326208:10
139954306373376:-3
139954306373376:-4
139954306373376:-5
139954306373376:-6
139954306373376:-7
主进程n从5开始递增5次,线程p从3开始递减10次,但主进程会等线程完成,并且不会出现生存周期的问题
通过返回多个值的方式,使用同一个值
也可以用同一个数p,主进程p从3开始递增5次,线程p从3开始递减10次
#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void* handle(void* p){
int* pn = (int*)p;
for(int i=0;i<10;++i){
sleep(1);
cout << pthread_self() << ":" << --*pn << endl;
}
delete pn;
return NULL;
}
pair<pthread_t,int*> test(){
int* p = new int(3);
pthread_t tid;
pthread_create(&tid,NULL,handle,p);
return {tid,p};
}
int main(){
cout << getpid() << endl;
cout << pthread_self() << endl;
auto [tid,p] = test(); // c++17
int n = 5;
for(int i=0;i<5;++i){
sleep(1);
cout << pthread_self() << ":" << ++n << endl;
}
pthread_join(tid,NULL);
return 0;
}
结果为:
[root@foundation1 C++7.13]# g++ thread2.cpp -pthread -std=c++17
[root@foundation1 C++7.13]# ./a.out
11325
140515561719616
140515543766784140515561719616::23
140515543766784:2
140515561719616:3
140515543766784140515561719616::23
140515543766784140515561719616::23
140515561719616140515543766784::23
140515543766784:2
140515543766784:1
140515543766784:0
140515543766784:-1
140515543766784:-2
并发过程中在2和3僵持,等待阶段开始递减