c++线程基本函数

创建线程和结束线程

交流群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,否则返回错误的编号。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351