文章目录
- 线程等待
- 线程终止
- return退出线程
- pthread_exit退出线程
- pthread_cancel取消线程
线程等待
哪个线程先运行?由调度器说的算。
但是主线程一定要是最后退出!
为什么需要线程等待?
- 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。(内存泄漏)
- 创建新的线程不会复用刚才退出线程的地址空间。
- 关心线程运行的结果数据!(获取线程的执行情况)
功能:等待线程结束
原型int pthread_join(pthread_t thread, void **value_ptr);
参数thread:线程IDvalue_ptr:它指向一个指针,后者指向线程的返回值
返回值:成功返回0;失败返回错误码
调用该函数的线程将挂起等待,直到id为thread
的线程终止。
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}return nullptr;//在这里默认线程就退出了
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");pthread_join(tid,nullptr);//主线程等待默认阻塞等待!cout<<"main thread quit!!"<<endl;return 0;
}
thread线程以不同的方法终止,通过pthread_join
得到的终止状态是不同的,
总结如下:
-
如果
thread
线程通过return
返回,value_ ptr
所指向的单元里存放的是thread
线程函数的返回值。 -
如果
thread
线程被别的线程调用pthread_ cancel
异常终掉,value_ ptr
所指向的单元里存放的是常数PTHREAD_ CANCELED
。 -
如果
thread
线程是自己调用pthread_exit
终止的,value_ptr
所指向的单元存放的是传给pthread_exit
的参数。 -
如果对
thread
线程的终止状态不感兴趣,可以传NULL给value_ ptr
参数。
获取返回值的原理
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}return (void*)1;//在这里默认线程就退出了
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");void*ret;pthread_join(tid,&ret);//主线程等待默认阻塞等待!cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;//注意不能用int,因为int4字节 void*8字节return 0;
}
在线程join
的时候不考虑异常是因为线程出异常了,整个进程都会终止!
线程终止
主线程退出了那么整个进程就退出了!
如果需要只终止某个线程而不终止整个进程,可以有三种方法:
-
从线程函数
return
。这种方法对主线程不适用,从main函数
return
相当于调用exit
。 -
线程可以调用
pthread_ exit
终止自己。 -
一个线程可以调用
pthread_ cancel
终止同一进程中的另一个线程。
*pthread_exit
*函数
功能:线程终止
原型void pthread_exit(void *value_ptr);
参数value_ptr:value_ptr不要指向一个局部变量。
返回值:无返回值,跟进程一样,线程结束的时候无法返回到它的调用者(自身)
需要注意
pthread_exit
或者return
返回的指针所指向的内存单元必须是全局的或者是用malloc
分配的,
不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。
*pthread_cancel
*函数
功能:取消一个执行中的线程
原型int pthread_cancel(pthread_t thread);
参数thread:线程ID
返回值:成功返回0; 失败返回错误码
exit
可以退出线程吗?
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <cstdlib>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}exit(11);
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");void*ret;pthread_join(tid,&ret);//主线程等待默认阻塞等待!cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;return 0;
}
很明显把整个进程都终止了!
所以exit
是用来终止进程的,不能用来终止线程!
return退出线程
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}return (void*)1;//在这里默认线程就退出了
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");void*ret;pthread_join(tid,&ret);cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;return 0;
}
pthread_exit退出线程
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <cstdlib>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}pthread_exit((void*)100);
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");void*ret;pthread_join(tid,&ret);cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;return 0;
}
pthread_cancel取消线程
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <cstdlib>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}pthread_exit((void*)100);
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");sleep(1);//只是为了保证新线程已经启动pthread_cancel(tid);void*ret;pthread_join(tid,&ret);//主线程等待默认阻塞等待!cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;return 0;
}