Linux多线程编程(一)

  • 2019 年 10 月 6 日
  • 笔记

一番码客 : 挖掘你关心的亮点。 http://efonfighting.imwork.net

1 – 线程创建

pthread_create

创建一个线程,函数的声明:

int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,                     void* (*start_routine)(void*), void* arg)  
  • para:
    • thread_out:创建线程后的标识符。
    • attr:设置线程属性。传NULL为默认属性。
    • start_routine:线程运行函数的函数指针。
    • arg:运行函数的参数,不使用参数则为NULL。
  • return:
    • 0:创建成功。
    • 非0:创建失败,常见错误返回代码EAGAIN(统限制创建新的线程,例如线程数目过多)和EINVAL(线程属性值非法)。

pthread_t

定义在 pthreadtypes.h

typedef unsigned long int pthread_t;  

线程的标识符。也就是前面创建线程时候传入的参数。

2 – 线程属性设置

pthread_attr_t

属性对象主要包括是否绑定、是否分离、堆栈地址、堆栈大小、优先级。默认的属性为非绑定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。pthread_attr_t结构的定义,定义在pthread.h

typedef struct  {      uint32_t flags;      void * stack_base;      size_t stack_size;      size_t guard_size;      int32_t sched_policy;      int32_t sched_priority;  } pthread_attr_t;  

属性设置

  • 初始化:pthread_attr_init
  • 默认属性:非绑定、非分离、1M堆栈、与父进程同样级别的优先级。
  • 设置:属性值只能通过相关函数(**pthread_attr_set×××**)进行设置,这个函数必须在pthread_create函数之前调用。
  • 属性操作函数:
/*      功能:初始化一个线程对象的属性      返回值:若是成功返回0,否则返回错误的编号      形参:attr指向一个线程属性的指针      说明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。pthread_attr_init实现时为属性对象分配了动态内存空间。  */  int pthread_attr_init(pthread_attr_t *attr);      /*      功能:销毁一个线程属性对象      返回值:若是成功返回0,否则返回错误的编号      形参:attr指向一个线程属性的指针      说明:经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。  */  int pthread_attr_destroy(pthread_attr_t *attr);    3、获取线程间的CPU亲缘性  int pthread_attr_getaffinity_np(pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针      说  明:获取线程的CPU亲缘属性      头文件:#include <pthread.h>  4、设置线程的CPU亲缘性  int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr         指向一个线程属性的指针              cpusetsize   指向CPU组的缓冲区大小              cpuset       指向CPU组的指针      说  明:通过指定cupset来设置线程的CPU亲缘性      头文件:#include <pthread.h>  5、获取线程分离状态属性  int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr          指向一个线程属性的指针              detachstate   保存返回的分离状态属性      说  明:获取线程分离状态属性      头文件:#include <pthread.h>  6、修改线程分离状态属性  int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr        指向一个线程属性的指针              detachstat  有两个取值                          PTHREAD_CREATE_DETACHED(分离)                          PTHREAD_CREATE_JOINABLE(非分离)      说  明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。      头文件:#include <pthread.h>  7、获取线程的栈保护区大小  int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              guardsize  返回获取的栈保护区大小      说  明:获取线程的栈保护区大小      头文件:#include <pthread.h>  8、设置线程的栈保护区大小  int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              guardsize  线程的栈保护区大小      说  明:参数提供了对栈指针溢出的保护。              默认为系统页大小              如果设置为0表示没有保护区。              大于0,则会为每个使用 attr 创建的线程提供大小至少为 guardsize 字节的溢出保护区      头文件:#include <pthread.h>  9、获取线程的作用域  int pthread_attr_getscope(pthread_attr_t *attr, int *scope);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              scope      返回线程的作用域      说  明:指定了作用域也就指定了线程与谁竞争资源      头文件:#include <pthread.h>  10、设置线程的作用域  int pthread_attr_setscope(pthread_attr_t *attr, int scope);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              guardsize  线程的作用域,可以取如下值                         PTHREAD_SCOPE_SYSTEM    与系统中所有进程中线程竞争                         PTHREAD_SCOPE_PROCESS   与当前进程中的其他线程竞争      说  明:指定了作用域也就指定了线程与谁竞争资源      头文件:#include <pthread.h>  11、获取线程的堆栈信息(栈地址和栈大小)  int pthread_attr_getstack(pthread_attr_t *attr, void **stackaddr, size_t *stacksize);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              stackaddr  返回获取的栈地址              stacksize  返回获取的栈大小      说  明:获取线程的堆栈地址和大小      头文件:#include <pthread.h>  12、设置线程堆栈区  int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              stackaddr  线程的堆栈地址:应该是可移植的,对齐页边距的                         可以用posix_memalign来进行获取              stacksize  线程的堆栈大小:应该是页大小的整数倍      说  明:设置堆栈区,将导致pthread_attr_setguardsize失效。      头文件:#include <pthread.h>  13、获取线程堆栈地址  int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              stackaddr  返回获取的栈地址      说  明:函数已过时,一般用pthread_attr_getstack来代替      头文件:#include <pthread.h>  14、设置线程堆栈地址  int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              stackaddr  设置线程堆栈地址      说  明:函数已过时,一般用pthread_attr_setstack来代替      头文件:#include <pthread.h>  15、获取线程堆栈大小  int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              stacksize  返回线程的堆栈大小      说  明:获取线程堆栈大小      头文件:#include <pthread.h>  16、设置线程堆栈大小  int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              guardsize  线程的栈保护区大小:应该是页大小的整数倍      说  明:设置线程堆栈大小:      头文件:#include <pthread.h>  17、获取线程的调度策略  int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              policy     返回线程的调度策略      说  明:获取线程的调度策略      头文件:#include <pthread.h>  18、设置线程的调度策略  int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              policy     线程的调度策略,有如下三种:                          SCHED_FIFO    先入先出策略                          SCHED_RR      轮转调度,类似于 FIFO,但加上了时间轮片算法                          SCHED_OTHER      系统默认策略      说  明:设置线程的调度策略      头文件:#include <pthread.h>  19、获取线程的调度参数  int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              param      返回获取的调度参数,该结构仅有一个从参数,如下                          struct sched_param                          {                              int sched_priority; /* Scheduling priority */                          };      说  明:获取线程的调度参数      头文件:#include <pthread.h>  20、设置线程的调度参数  int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param *param);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              param      要设置的调度参数      说  明:设置线程的调度参数      头文件:#include <pthread.h>  21、获取线程是否继承调度属性  int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr          指向一个线程属性的指针              inheritsched  返回继承调度属性的设置      说  明:获取线程是否继承调度属性      头文件:#include <pthread.h>  22、设置线程是否继承调度属性  int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);      返回值:若是成功返回0,否则返回错误的编号      形  参:              attr       指向一个线程属性的指针              guardsize  设置线程是否继承调度属性                          PTHREAD_INHERIT_SCHED:调度属性将继承于正创建的线程                                                 attr中的设置将被忽略                          PTHREAD_EXPLICIT_SCHED 调度属性将被设置为attr中指定的属性值      说  明:      头文件:#include <pthread.h>  

线程参数传递

参数传递的是指针。代码中将value的值传入。

pthread_create(&id, &attr, run, &value);  

然后进行指针变量类型转换就可得到值。

int value=*(int *)ptr;  

3 – 线程优先级

主要涉及sched_parampthread_attr_setschedparampthread_attr_getschedparam等方法。

优先级变量存放在结构sched_param中。用pthread_attr_getschedparampthread_attr_setschedparam进行存放,一般说来,我们总是先取优先级,对取得的值修改后再存放回去。

免费知识星球: 一番码客-积累交流 微信公众号:一番码客 微信:Efon-fighting 网站:http://efonfighting.imwork.net