Linux之线程控制
线程控制
由于线程是后来才引用进来的,因此,在编译链接时需要加 -lpthread来引入外部库(POSIX)
创建线程
#include <pthread.h>
//函数原型
int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void *(*start_routine)(void*), void *arg);
//参数
thread :返回线程ID
attr : 线程属性,默认为NULL
start_routine :是个线程地址, 线程启动后要执行的函数(是一个回调函数)
arg : 线程函数的参数,只有一个,如果实在C++的类中使用,则线程函数必须设置为 static 类型,因为C++中我们看到的不一定是真实的
// 返回值
成功返回0,失败返回错误码
看个例子:
#include <iostream>
#include <pthread.h>
using namespace std;
void* Func(void* arg)
{
int a=10;
int b=20;
cout<<a+b<<endl;
return (void*)(a+b);
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,Func,(void*)NULL);
pthread_join(tid,NULL); //线程等待
return 0;
}
在上面的例子中,应该看到我在创建函数下面加了一个线程等待的函数,为什么呢?
线程等待
什么是线程等待? 线程等待就是等待一个线程是否完成任务,而后选择是否关闭该线程并释放该线程所占用的资源
为什么需要线程等待? |
---|
答:一个线程的创建是要占用资源(地址空间),并且他不会自动释放内存,而如果一个线程已经退出但并没有释放资源,那么会造成系统可用资源越来越少 |
//函数原型
int pthread_join(pthread_t thread, void **value_ptr);
参数
thread:线程ID
value_ptr:它指向一个指针,后者指向线程的返回值,如果不关心返回值可设置为NULL
返回值:
成功返回0;失败返回错误码
当调用该函数的线程将挂起等待,直到退出线程的 id == thread时会以不同的方式终止,通过pthread_join 得到的终止状态是不同的。
1. 如果thread线程通过return返回,value_ ptr所指向的单元里存放的是thread线程函数的返回值。
2. 如果thread线程被别的线程调用pthread_ cancel异常终掉,value_ ptr所指向的单元里存放的是常数 PTHREAD_ CANCELED(值等于-1)。
3. 如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。
4. 如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数。
线程终止
这个很好理解,就是终止线程。
//函数原型
void pthread_exit(void *value_ptr);
参数
value_ptr:value_ptr不要指向一个局部变量。
返回值:
无返回值,跟进程一样,线程结束的时候无法返回到它的调用者(自身)
需要注意 pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。
线程分离
前面我们说过,在线程结束我们必须要对该线程做点什么,否则会导致系统可用资源越来越少,当时我们说的是用pthread_join函数来操作,显然,呢个看起来是有点麻烦,其实也不麻烦。那有没有简单点的操作呢?当然是有的。
// 函数原型
int pthread_detach(pthread_t thread);
// 可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离:
pthread_detach ( pthread_self() ) //线程自身分离
- 默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏。
- 如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。
- joinable和分离是冲突的,一个线程不能既是joinable又是分离的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
void *thread_run( void * arg )
{
pthread_detach(pthread_self());
printf("%s\n", (char*)arg);
return NULL;
}
int main( )
{
pthread_t tid;
if ( pthread_create(&tid, NULL, thread_run, "thread1 run...") != 0 )
{
printf("create thread error\n");
return 1;
}
int ret =0;
sleep(1);//很重要,要让线程先分离,再等待
if ( pthread_join(tid, NULL ) == 0 ) ;
printf("pthread wait success\n");
}
else
{
printf("pthread wait failed\n");
ret = 1;
}
return ret;
}