Linux线程操作(创建,终止,等待,分离)
在使用Linux线程库时,需要包含头文件<pthread.h>,而且在链接时,需要包含-lphread选项。
创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *
(*start_routine)(void*), void *arg);
thread参数是输出型参数,会将thread指向的变量的值设置为线程ID,attr参数是设置线程的属性,为NULL表示使用默认属性,start_routine参数是一个函数指针,指向参数类型为void*,返回值类型为void*的一个函数,例如下面的函数
void* func(void* arg);
而最后一个参数arg会作为func函数的参数。
返回值为0表示成功,失败则返回错误码
pthreads函数在失败时不会像其他POSIX函数一样设置全局变量errno,而是返回错误码。
pthreads函数同样也提供了线程内的errno变量,以支持其他使用errno的代码。对于pthreads函数的错误,建议使用返回值判定,因为读取返回值的开销要更小。
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
void* thread_func(void* arg)
{
return NULL;
}
int main()
{
pthread_t thread;
int err = pthread_create(&thread, NULL, thread_func, NULL);
if(err)
{
fprintf(stderr, "pthread_create : %s\n", strerror(err));
exit(EXIT_FAILURE);
}
pthread_join(thread, NULL);
return 0;
}
现在可以创建线程为我们完成任务了。
获取线程ID
pthread_t pthread_self(void);
终止线程
只终止线程而不终止整个进程,可使用如下接口
void pthread_exit(void *value_ptr);
value_ptr是线程退出时交给主线程的值,也就是线程的返回值,主线程可通过等待线程获得该值创建线程时会传入一个函数指针,这个函数指针指向的函数会返回一个void*类型的值,也就是线程的返回值。
注意返回的指针不要指向局部变量,因为返回时该局部变量已经被销毁了。
int pthread_cancel(pthread_t thread);
thread是线程ID,可以直接取消该线程。如果要使用,一般是主线程取消其他线程。在其他线程中取消主线程是未定义行为。
返回值为0表示成功,失败返回错误码。
需要注意在线程中使用exit函数时,会退出整个进程。
线程等待
int pthread_join(pthread_t thread, void **value_ptr);
可以等待线程ID为thread的线程执行完任务,value_ptr指向线程的返回值,为NULL表示不关心返回值。
注意返回值有以下几种情况:
线程通过return返回,得到的返回值就是return的值
线程被调用pthread_cancel终止,value_ptr所指向的单元里存放常数PTHREAD_ CANCELED
线程调用pthread_exit终止,value指向的值是传给pthread_exit的参数
等待线程是为了回收这个线程的资源,避免造成类似僵尸进程的问题。
分离线程
默认情况下创建的线程是joinable的,线程退出后需要等待他以便回收资源。
如果不关心返回值,join是一种负担,这时,可以告诉系统,线程退出时,自动释放线程资源
int pthread_detach(pthread_t thread);
可以是线程组内其他线程对目标线程进行分离,也可以是线程分离自身
pthread_detach(pthread_self());
成功返回0,失败返回错误码
需要注意,线程不能既是joinable又是可分离的,也就是说,你不能等待一个被分离的线程
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
void* thread_func(void* arg)
{
pthread_detach(pthread_self());
return NULL;
}
int main()
{
pthread_t thread;
int err = pthread_create(&thread, NULL, thread_func, NULL);
if(err)
{
fprintf(stderr, "pthread_create : %s\n", strerror(err));
exit(EXIT_FAILURE);
}
//确保线程已经分离
sleep(1);
err = pthread_join(thread, NULL);
if(err)
{
fprintf(stderr, "pthread_join : %s\n", strerror(err));
exit(EXIT_FAILURE);
}
else
{
printf("pthread_join success\n");
}
pthread_join(thread, NULL);
return 0;
}
可用这段代码进行测试。