创建线程和结束线程
交流群728483370,一起学习加油!
(1)线程创建函数
int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
功能:创建一个具有指定参数的线程。
形参:thread是要创建的线程的线程ID指针。
pthread_t类型的定义是typedef unsigned long int pthread_t;(打印时要使用%lu或%u方式)。
attr:创建线程时的线程属性(设置NULL表示使用默认线程属性)。
start_routine:指向的是新线程将运行的函数。线程一旦被创建好,内核就可以调度内核线程来执行start_routine函数指针所指向的函数了。
arg:指向的是运行函数的形参。
返回值:若是成功建立线程返回0,否则返回错误的编号。
(2)等待线程结束函数
int pthread_join(pthread_t thread, void **retval);
功能:这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回
形参:thread是被等待的线程标识符。
retval:一个用户定义的指针,它可以用来存储被等待线程的返回值。
返回值:成功返回0,否则返回错误的编号。
错误码:
①EDEADLK:可能引起死锁,比如两个线程互相针对对方调用pthread_join,或者线程对自身调用pthread_join。
②EINVAL:目标线程是不可回收的,或者已经有其他线程在回收目标线程。
③ESRCH:目标线程不存在。
(3)线程退出函数
void pthread_exit(void *retval);
功能:线程函数在结束时调用此函数,以确保安全、干净地退出。
形参:retval是函数的返回指针,只要pthread_join中的第二个参数retval不是NULL,这个值将被传递给retval。pthread_exit函数通过retval参数向线程的回收者传递其退出信息。他执行完之后不会返回到调用者,而且永远不会失败。
(4)线程取消函数
int pthread_cancel(pthread_t thread);
功能:取消某个线程的执行。
形参:thread是要取消线程的标识符ID。
返回值:若是成功返回0,否则返回错误的编号。
但是,接收到取消请求的目标线程可以决定是否允许被取消以及如何取消,这分别由如下两个函数完成。
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
这两个函数的第一个参数分别用于设置线程的取消状态(是否允许取消)和取消类型(如何取消),第二个参数则分别记录线程原来的取消状态和取消类型。
state参数有两个可选值:
PTHREAD_CANCEL_CNABLE,允许线程被取消。它是线程被创建时的默认取消状态。
PTHREAD_CANCEL_DISABLE,禁止线程被取消。这种情况下,如果一个线程收到取消请求,则它会将请求挂起,直到该线程允许被取消。
type参数也有两个可选值:
PTHREAD_CANCEL_ASYNCHRONOUS,线程随时都可以被取消。它将使得接收到取消请求的目标线程立即采取行动。
PTHREAD_CANCEL_DEFERRED,允许目标线程推迟行动,直到它调用了下面几个所谓的取消点函数中的一个:pthread_join、pthread_testcancel、pthread_cond_wait、pthread_cond_timedwait、sem_wait和sigwait。根据POSIX标准,其他可能阻塞的系统调用,比如read、wait,也可以成为取消点。不过为了安全起见,最好在可能会被取消的代码中调用pthread_testcancel函数设置取消点。
(5)获取当前线程ID函数
pthread_t pthread_self (void);
功能:获取当前调用线程的线程ID。
返回值:当前线程的线程ID标识。
(6)分离释放线程函数
int pthread_detach (pthread_t thread);
功能:线程资源释放方式设置函数。
形参:thread是要释放线程的标识符ID。
返回值:若是成功返回0,否则返回错误的编号。
其他说明:linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态。一个线程默认的状态是joinable,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时,都不会释放线程所占用堆栈和线程描述符(总计8K多),只有当调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己设置,如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。如果线程状态为joinable,需要在之后适时调用pthread_join。
(7)比较两个线程是否为同一线程
int pthread_equal (pthread_t thread1, pthread_t thread2);
功能:判断两个线程ID是否是同一个。
形参:thread1是要比较的线程的标识符ID1;thread2是要比较的线程的标识符ID2。
返回值:不相等返回0,相等非零。
(8)创建线程私有数据
int pthread_key_create (pthread_key_t *key, void (*destr_function) (void *));
功能:创建线程私有数据TSD,提供线程私有的全局变量。使用同名而不同内存地址的线程私有数据结构。
形参:Key是线程私有数据。
第二个参数:如果第二个参数不为空,在线程退出时将以key所关联数据为参数调用其指向的资源释放函数,以释放分配的缓冲区。
其他说明:不论哪个线程调用pthread_key_create()函数,所创建的key都是所有线程可访问的,但各个线程可根据自己的需要往key中填入不同的值 相当于提供了同名不同值的全局变量,各线程对自己私有数据操作互相不影响。
注销线程私有数据
int pthread_key_delete (pthread_key_t *key);
该函数并不检查当前是否有线程正是用该TSD,也不会调用清理函数(destr_function) 将TSD释放以供下一次调用pthread_key_create()使用。
(9)读写线程私有数据
int pthread_setspecific (pthread_key_t key, const void *pointer); //写
void pthread_getspecific (pthread_key_t key); //读
函数pthread_setspecific()将pointer的值(非内容)与key相关联。函数pthread_getspecific()将与key相关联的数据读出来。所有数据都设置为void *,因此可以指向任何类型的数据。
线程属性
(1)初始化线程对象属性
int pthread_attr_init (pthread_attr_t *attr);
功能:pthread_attr_init实现时为属性对象分配了动态内存空间。
形参:attr是指向一个线程属性的指针。
返回值:若是成功返回0,否则返回错误的编号。
(2)销毁线程对象属性
int pthread_attr_destroy (pthread_attr_t *attr);
功能:经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。只有再次初始化后才能继续使用。
形参:attr是指向一个线程属性的指针。
返回值:若是成功返回0,否则返回错误的编号。
(3)获取线程分离状态属性
int pthread_attr_getdetachstate (pthread_attr_t *attr, int *detachstate);
功能:获取线程分离状态属性;另外,pthread_detach()是分离释放线程资源函数
形参:attr是指向一个线程属性的指针。
detachstate:保存返回的分离状态属性。
返回值:若是成功返回0,否则返回错误的编号。
(4)修改线程分离状态属性
int pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate);
功能:修改线程分离状态属性。
形参:attr是指向一个线程属性的指针。
detachstate:其含义是线程的脱离状态,它有两个可选值,分别是PTHREAD_CREATE_JOINABLE(可连接)以及PTHREAD_CREATE_DETACHED(分离)。前者指定线程是可以被回收的,后者使调用线程脱离与进程中其他线程同步。脱离了与其他线程同步的线程成为”脱离线程”。脱离线程在退出时将自行释放其占用的系统资源。线程创建时该属性的默认值是PTHREAD_CREATE_JOINABL。此外,我们可以使用pthread_detach函数直接将线程设置为脱离线程。(上述detachstate的含义相同,之后相同含义的参数,都只介绍一次)
返回值:若是成功返回0,否则返回错误的编号。
(5)获取线程的CPU亲缘性
int pthread_attr_getaffinity_np (pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset);
功能:获取线程的CPU亲缘属性。
形参:attr是指向一个线程属性的指针。
cpusetsize:指向CPU组的缓冲区大小。
cpuset:指向CPU组的指针。
返回值:若是成功返回0,否则返回错误的编号。
(6)设置线程的CPU亲缘性
int pthread_attr_setaffinity_np (pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);
功能:通过指定cupset来设置线程的CPU亲缘性。
形参:attr是指向一个线程属性的指针。
cpusetsize:指向CPU组的缓冲区大小。
cpuset:指向CPU组的指针。
返回值:若是成功返回0,否则返回错误的编号。
(7)获取线程的作用域
int pthread_attr_getscope (const pthread_attr_t *attr, int *scope);
功能:指定了作用域也就指定了线程与谁竞争资源。
形参:attr是指向一个线程属性的指针;scope是返回线程的作用域。
返回值:若是成功返回0,否则返回错误的编号。
(8)设置线程的作用域
int pthread_attr_setscope (pthread_attr_t *attr, int scope);
功能:指定了作用域也就指定了线程与谁竞争资源
形参:attr是指向一个线程属性的指针。
scope:线程间竞争CPU的范围,即线程优先级的有效范围。POSIX标准定义了该属性可以取以下两个值:PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示目标线程与系统中所有线程一起竞争CPU的使用,后者表示目标线程仅与其他隶属于同一进程的线程竞争CPU的使用。
返回值:若是成功返回0,否则返回错误的编号。
(9)获取线程的栈保护区大小
int pthread_attr_getguardsize (const pthread_attr_t *attr, size_t *guardsize);
功能:获取线程的栈保护区大小。
形参:attr是指向一个线程属性的指针。
guardsize:返回获取的栈保护区大小。
返回值:若是成功返回0,否则返回错误的编号。
(10)设置线程的栈保护区大小
int pthread_attr_setguardsize (pthread_attr_t *attr, size_t *guardsize);
功能:参数提供了对栈指针溢出的保护。默认为系统页大小。
形参:attr是指向一个线程属性的指针。
guardsize:线程的栈保护区大小。如果guardsize大于0,则系统创建线程的时候会在其堆栈的尾部额外分配guardsize字节的空间,作为保护堆栈不被错误地覆盖的区域。如果guardsize等于0,则系统不为新创建的线程设置堆栈保护区。如果使用者通过pthread_attr_setstack()或pthread_attr_setstackaddr()函数手动设置线程的堆栈,则guardsize属性将被忽略。
返回值:若是成功返回0,否则返回错误的编号。
(11)获取线程的堆栈信息(栈地址和栈大小)
int pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr, size_t *stacksize);
功能:获取线程的堆栈地址和大小。
形参:attr是指向一个线程属性的指针。
stackaddr:返回获取的栈地址。
stacksize:返回获取的栈大小。
返回值:若是成功返回0,否则返回错误的编号。
(12)设置线程的堆栈区
int pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stacksize);
功能:设置堆栈区,将导致pthread_attr_setguardsize失效。
形参:attr是指向一个线程属性的指针。
stackaddr:线程的堆栈地址,应该是可移植的,对齐页边距的,可以用posix_memalign来进行获取。
stacksize:线程的堆栈大小,应该是页大小的整数倍。
返回值:若是成功返回0,否则返回错误的编号。
(13)获取线程堆栈地址
int pthread_attr_getstackaddr (const pthread_attr_t *attr, void **stackaddr);
功能:一般用pthread_attr_getstack来代替。
形参:attr是指向一个线程属性的指针;stackaddr是返回获取的栈地址。
返回值:若是成功返回0,否则返回错误的编号。
(14)设置线程堆栈地址
int pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr);
功能:一般用pthread_attr_setstack来代替。
形参:attr是指向一个线程属性的指针;stackaddr是设置线程堆栈地址。
返回值:若是成功返回0,否则返回错误的编号。
(15)获取线程堆栈大小
int pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *stacksize);
功能:获取线程堆栈大小。
形参:attr是指向一个线程属性的指针;stacksize是返回线程的堆栈大小。
返回值:若是成功返回0,否则返回错误的编号。
(16)设置线程堆栈大小
int pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize);
功能:设置线程堆栈大小。
形参:attr是指向一个线程属性的指针。
stacksize:设置线程的堆栈大小,stack属性的合法值包括PTHREAD_STACK_MIN,该线程的用户栈大小将使用默认堆栈大小,为某个线程所需最小堆栈大小,但对于所有线程,这个大小可能无法接受,具体指定的大小,即使用线程的用户堆栈大小的数值,必须不小于最小堆栈大小PTHREAD_STACK_MIN。
返回值:若是成功返回0,否则返回错误的编号。
(17)获取线程的调度策略
int pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy);
功能:获取线程的调度策略。
形参:attr是指向一个线程属性的指针;policy是返回线程的调度策略。
返回值:若是成功返回0,否则返回错误的编号。
按照如下方法使用sched_get_priority_max()和sched_get_priority_min(),可以得到优先级的最大值和最小值。
头文件:#include <pthread.h> #include <sched.h>
调用形式:
#include <sched.h>
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);
(18)设置线程的调度策略
int pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);
头文件:#include <pthread.h> #include <sched.h>
功能:设置线程的调度策略。
形参:attr是指向一个线程属性的指针。
policy:线程的调度策略,POSIX指定了3种调度策略属性:SCHED_FIFO表示先入先出策略,SCHED_RR表示轮转调度(这两种调度方法都具备实时调度功能,但只能用于以超级用户身份运行的进程),SCHED_OTHER是系统默认策略,SCHED_OTHER是不支持优先级使用的。SCHED_FIFO和SCHED_RR支持优先级的使用,它们分别为1和99,数值越大优先级越高。
返回值:若是成功返回0,否则返回错误的编号。
(19)获取线程的调度参数
int pthread_attr_getschedparam (const pthread_attr_t *attr, struct sched_param *param);
头文件:#include <pthread.h> #include <sched.h>
功能:获取线程的调度参数。
形参:attr是指向一个线程属性的指针;param是返回获取的调度参数。
返回值:若是成功返回0,否则返回错误的编号。
(20)设置线程的调度参数
int pthread_attr_setschedparam (pthread_attr_t *attr, const struct sched_param *param);
头文件:#include <pthread.h> #include <sched.h>
功能:设置线程的调度参数,用于设置优先级。
形参:attr是指向一个线程属性的指针。
param:要设置的调度参数,其类型是sched_param结构体。至少需要定义这个数据成员
struct sched_param
{
int sched_priority;
/*该成员表示线程运行优先级*/
};
sched_param可能还有其他的数据成员,以及多个用来返回和设置最小优先级、最大优先级、调度器、参数等的函数。如果调度策略是SCHED_FIFO或SCHED_RR,那么要求具有值的唯一成员是sched_priority。
返回值:若是成功返回0,否则返回错误的编号。
(21)获取线程是否继承调度属性
int pthread_attr_getinheritsched (const pthread_attr_t *attr, int *inheritsched);
头文件:#include <pthread.h> #include <sched.h>
功能:获取线程是否继承调度属性。
形参:attr是指向一个线程属性的指针;inheritsched是返回继承调度属性的设置。
返回值:若是成功返回0,否则返回错误的编号。
(22)设置线程继承调度属性
int pthread_attr_setinheritsched (pthread_attr_t *attr, int inheritsched);
头文件:#include <pthread.h> #include <sched.h>
功能:设置线程是否继承调度属性。
形参:attr是指向一个线程属性的指针。
Inheritsched:设置线程是否继承调用线程的调度属性,可能取值如下:
PTHREAD_INHERIT_SCHED表示新线程沿用其创建者的线程调度参数,这种情况下再设置新线程的调度参数属性将没有任何效果。PTHREAD_EXPLICIT_SCHED表示调用者要明确地指定新线程的调度参数。
返回值:若是成功返回0,否则返回错误的编号。
网友评论