#include <pthread.h>
void * threadFun(void* args){
//......
}
pthread_t myThread;
pthread_create(&myThread, NULL, ThreadFun, NULL);
程序中,pthread_create() 函数需要传递 4 个参数,其中第二个参数 NULL 表示以系统默认的属性创建线程。
那么,线程都有哪些属性,线程的属性又该如何设置或者修改呢?接下来,我们将一一为大家解开这些疑惑。您可以阅读《如何创建一个线程?》,系统地学习如何创建线程。
#include <pthread.h> pthread_attr_t myAttr;由此,我们就定义了一个表示线程属性的变量。使用此变量前,必须调用 pthread_attr_init() 函数进行初始化,该函数的语法格式如下:
int pthread_attr_init(pthread_attr_t * attr);此函数定义在 <pthread.h> 头文件中,函数执行成功时,返回数字 0,反之返回非零数。
pthread_attr_init(&myAttr);通过调用 pthread_attr_init() 函数,myAttr 变量就拥有了系统默认的线程属性。在此基础上,我们可以根据需要对 myAttr 变量的属性值进行修改。
typedef struct
{
int __detachstate;
int __schedpolicy;
struct sched_param __schedparam;
int __inheritsched;
int __scope;
size_t __guardsize;
int __stackaddr_set;
void* __stackaddr;
size_t __stacksize;
} pthread_attr_t;
接下来,我们将从中挑选出几个常用的属性,给您讲解它们的功能以及修改的方法。int pthread_attr_getdetachstate(const pthread_attr_t * attr,int * detachstate); int pthread_attr_setdetachstate(pthread_attr_t *sttr,int detachstate);pthread_attr_getdetachstate() 函数用于获取 __detachstate 属性的值,detachstate 指针用于接收 __detachstate 属性的值;pthread_attr_setdetachstate() 函数用于修改 __detachstate 属性的值,detachstate 整形变量即为新的 __detachstate 属性值。两个函数执行成功时返回数字 0,反之返回非零数。
int pthread_detach(pthread_t thread);函数执行成功时返回数字 0 ,反之返回非零数。
<pthread.h> 头文件提供了如下两个函数,专门用于访问和修改 __schedpolicy 属性:其中,SCHED_OTHER 调度算法不支持为线程设置优先级,而另外两种调度算法支持。
int pthread_attr_getschedpolicy(const pthread_attr_t *, int * policy) int pthread_attr_setschedpolicy(pthread_attr_*, int policy)pthread_attr_getschedpolicy() 函数用于获取当前 __schedpolicy 属性的值;pthread_attr_setschedpolicy() 函数用于修改 __schedpolicy 属性的值。函数执行成功时,返回值为数字 0,反之返回非零数。
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param); int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);其中,param 参数用于接收或者修改 __scheparam 属性的优先级,它是 sched_param 结构体类型的变量,定义在 <sched.h> 头文件中,内部仅有一个 sched_priority 整形变量,用于表示线程的优先级。函数执行成功时返回数字 0,反之返回非零数。
不同的操作系统,线程优先级的值的范围不同,您可以通过调用如下两个系统函数获得当前系统支持的最大和最小优先级的值:当需要修改线程的优先级时,我们只需创建一个 sched_param 类型的变量并为其内部的 sched_priority 成员赋值,然后将其传递给 pthrerd_attr_setschedparam() 函数。
int sched_get_priority_max(int policy); //获得最大优先级的值 int sched_get_priority_min(int policy); //获得最小优先级的值其中,policy 的值可以为 SCHED_FIFO、SCHED_RR 或者 SCHED_OTHER,当 policy 的值为 SCHED_OTHER 时,最大和最小优先级的值都为 0。
//获取 __inheritsched 属性的值 int pthread_attr_getinheritsched(const pthread_attr_t *attr,int *inheritsched); //修改 __inheritsched 属性的值 int pthread_attr_setinheritsched(pthread_attr_t *attr,int inheritsched);其中在 pthread_attr_setinheritsched() 函数中,inheritsched 参数的可选值有两个,分别是:
//获取 __scope 属性的值 int pthread_attr_getscope(const pthread_attr_t * attr,int * scope); //修改 __scope 属性的值 int pthread_attr_setscope(pthread_attr_t * attr,int * scope);当调用 pthread_attr_setscope() 函数时,scope 参数的可选值有两个,分别是:
当函数执行成功时,返回值为数字 0,反之返回非零数。Linux系统仅支持 PTHREAD_SCOPE_SYSTEM,即所有线程之间争夺 CPU 资源。
//获取当前栈内存的大小 int pthread_attr_getstacksize(const pthread_attr_t * attr,size_t * stacksize); //修改栈内存的大小 int pthread_attr_setsstacksize(pthread_attr_t * attr,size_t * stacksize);函数执行成功时,返回值为数字 0,反之返回非零数。
int pthread_attr_getguardsize(const pthread_attr_t *restrict attr,size_t *restrict guardsize); int pthread_attr_setguardsize(pthread_attr_t *attr ,size_t *guardsize);pthread_attr_setguardsize() 函数中,设置警戒缓冲区的大小为参数 guardsize 指定的字节数。函数执行成功时返回数字 0,反之返回非零数。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
//myThread1 线程执行的函数
void *Thread1(void *arg)
{
printf("Thread1 正在执行\n");
printf("http://c.biancheng.net\n");
printf("Thread1 执行完毕\n");
return NULL;
}
//myThread2 线程执行的函数
void* Thread2(void* arg)
{
printf("Thread2 正在执行\n");
printf("C语言中文网\n");
printf("Thread2 执行完毕\n");
return NULL;
}
int main(int argc,char *argv[])
{
int num1, num2, res;
//创建两个线程
pthread_t mythread1, mythread2;
//创建两个表示线程优先级的变量
struct sched_param param1, param2;
//创建两个表示线程属性的变量
pthread_attr_t myAttr1, myAttr2;
//接收 2 个整数,用于设定线程的优先级
if (argc != 3) {
printf("未向程序传入 2 个表示优先级的数字\n");
return 0;
}
//初始化线程属性
res = pthread_attr_init(&myAttr1);
if (res != 0) {
printf("myAttr1 init Fail\n");
}
res = pthread_attr_init(&myAttr2);
if (res != 0) {
printf("myAttr1 init Fail\n");
}
//设置 myAttr1 的 __detachstate 属性值为 PTHREAD_CREATE_DETACHED
//遵循 myAttr1 属性的线程执行函数完毕后会自行释放占用私有资源,不支持 pthread_join() 函数
res = pthread_attr_setdetachstate(&myAttr1, PTHREAD_CREATE_DETACHED);
if (res != 0) {
printf("myAttr1 set_detachstate Fail\n");
}
//设置 myAttr1 的 __scope 属性值为 PTHREAD_SCOPE_SYSTEM
//遵循 myAttr1 属性的线程将同系统中的所有其它线程争夺 CPU 资源
res = pthread_attr_setscope(&myAttr1, PTHREAD_SCOPE_SYSTEM);
if (res != 0) {
printf("myAttr1 set_scope Fail\n");
}
//设置 myAttr2 的 __scope 属性值为 PTHREAD_SCOPE_SYSTEM
//遵循 myAttr2 属性的线程将同系统中的所有其它线程争夺 CPU 资源
res = pthread_attr_setscope(&myAttr2, PTHREAD_SCOPE_SYSTEM);
if (res != 0) {
printf("myAttr2 set_scope Fail\n");
}
//设置 myAttr1 的 __schedpolicy 属性值为 SCHED_FIFO
//系统会以实时调用的方式执行遵循 myAttr1 属性的线程
res = pthread_attr_setschedpolicy(&myAttr1, SCHED_FIFO);
if (res != 0) {
printf("myAttr1 set_policy Fail\n");
}
//设置 myAttr2 的 __schedpolicy 属性值为 SCHED_FIFO
//系统会以实时调用的方式执行遵循 myAttr2 属性的线程
res = pthread_attr_setschedpolicy(&myAttr2, SCHED_FIFO);
if (res != 0) {
printf("myAttr2 set_policy Fail\n");
}
//设置 myAttr1 的 __inheritsched 属性值为 PTHREAD_EXPLICIT_SCHED
//myAttr1 属性的线程将遵循自定义的线程属性
res = pthread_attr_setinheritsched(&myAttr1, PTHREAD_EXPLICIT_SCHED);
if (res != 0) {
printf("myAttr1 set_inheritsched fail\n");
}
//设置 myAttr2 的 __inheritsched 属性值为 PTHREAD_EXPLICIT_SCHED
//myAttr2 属性的线程将遵循自定义的线程属性
res = pthread_attr_setinheritsched(&myAttr2, PTHREAD_EXPLICIT_SCHED);
if (res != 0) {
printf("myAttr2 set_inheritsched fail\n");
}
//想 argv[] 数组中的字符转换为数字
num1 = atoi(argv[1]);
num2 = atoi(argv[2]);
// 分别将 num1 和 num2 作为线程优先级的值
param1.sched_priority = num1;
param2.sched_priority = num2;
//设置 myAttr1 属性的优先级为 param1
res = pthread_attr_setschedparam(&myAttr1, ¶m1);
if (res != 0) {
printf("param1 setscheparam Fail\n");
}
//设置 myAttr2 属性的优先级为 param2
res = pthread_attr_setschedparam(&myAttr2, ¶m2);
if (res != 0) {
printf("param2 setscheparam Fail\n");
}
//创建新线程并遵循 myAttr1 属性
res = pthread_create(&mythread1, &myAttr1, Thread1, NULL);
if (res != 0) {
printf("mythread1 create Fail\n");
}
//创建新线程并遵循 myAttr2 属性
res = pthread_create(&mythread2, &myAttr2, Thread2, NULL);
if (res != 0) {
printf("mythread2 create Fail\n");
}
sleep(5); //等待 mythread1 和 mythread2 两个线程执行完
//尝试 pthread_join() 函数等待 mythread1 线程执行结束
res = pthread_join(mythread1, NULL);
if (res != 0) {
if (res == EINVAL) {
printf("mythread1不支持调用 pthread_join()函数\n");
}
}
//尝试等待 mythread2 线程执行结束
res = pthread_join(mythread2, NULL);
if (res != 0) {
printf("mythread2 has finished\n");
}
printf("主线程执行完毕\n");
return 0;
}
假设程序编写在 thread.c 文件中,执行过程如下:
[root@localhost ~]# gcc thread.c -o thread.exe -lpthread
[root@localhost ~]# ./thread.exe 30 3
Thread1 正在执行
http://c.biancheng.net
Thread1 执行完毕
Thread2 正在执行
C语言中文网
Thread2 执行完毕
mythread1不支持调用 pthread_join()函数
主线程执行完毕
[root@localhost ~]# ./thread.exe 3 30
Thread2 正在执行
C语言中文网
Thread2 执行完毕
Thread1 正在执行
http://c.biancheng.net
Thread1 执行完毕
mythread1不支持调用 pthread_join()函数
主线程执行完毕
版权说明:Copyright © 广州松河信息科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州松河信息科技有限公司 版权所有