线程的属性
脱离线程:不向主线程返回信息,不需要主线程等待.
通过两种方法创建:
调用pthread_detach;
修改线程的属性. <- 这里使用
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
初始化一个线程属性对象.
pthread_destroy
回收一个线程属性对象.
#include <pthread.h>
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
这个属性允许我们无需对线程进行合并:
| PTHREAD_CREATE_JOINABLE 默认.
| PTHREAD_CREATE_DETACHED 不能调用pthread_join来获得另一个线程的退出状态.
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
控制线程的调度方式:
| SCHED_OTHER 默认
| SCHED_RP 循环(round_robin) <- 下面2个调度方式具备实时调度功能,需要root权限.
| SCHED_FIFO 先进先出
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
和schedpolicy配合使用,控制SCHED_OTHER线程的调度策略.
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit);
| PTHREAD_EXPLICIT_SCHED 调度由属性明确设置.
| PTHREAD_INHERIT_SCHED 新线程沿用创建者的属性.
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
控制一个线程调度的计算方式,目前Linux只支持PTHREAD_SCOPE_SYSTEM.
int pthread_attr_setstacksize(pthread_attr_t *attr, int scope);
int pthread_attr_getstacksize(const pthread_attr_t *attr, int *scope);
控制线程创建的栈大小,单位字节.可选.
Linux在实现线程时,默认的栈很大,这个属性有点多余.
创建脱离线程:
/*
* 线程属性-创建脱离线程
* 主线程不等待子线程结束,只通过thread_finished标志来检测子线程是否已结束,并显示线程之间仍然共享的变量.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void *thread_function(void *arg);
char g_message[] = "Hello World!";
int g_thread_finished = 0;
int main(){
int res;
pthread_t a_thread;
pthread_attr_t thread_attr;
res = pthread_attr_init(&thread_attr);
if(res != 0){
perror("Attribute creation failed");
exit(EXIT_FAILURE);
}
res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
if(res != 0){
perror("Setting detached attribute failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread, &thread_attr,
thread_function, (void *)g_message);
if(res != 0){
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
(void)pthread_attr_destroy(&thread_attr);
while(!g_thread_finished){
printf("Waiting for thread to say it's finished
\n");
sleep(1);
}
printf("Other thread finished, bye!\n");
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg){
printf("thread_function is running. Argument was %s\n", (char *)arg);
sleep(4);
printf("Second thread setting finished flag, and exit now\n");
g_thread_finished = 1;
pthread_exit(NULL);
} 执行结果:
$ gcc -D_REENTRANT thread5.c -o thread5 -lpthread
$ ./thread5
Waiting for thread to say it's finished
thread_function is running. Argument was Hello World!
Waiting for thread to say it's finished
Waiting for thread to say it's finished
Waiting for thread to say it's finished
Second thread setting finished flag, and exit now
Other thread finished, bye! --
FROM: Linux程序设计