Linux编程-线程

本文最后更新于:1 年前

  • 线程是CPU调度的基本单位

  • 线程有自己的堆栈和局部变量,但是没有独立的地址空间(同一个进程内的线程共享进程的地址空间)

线程函数

pthread_create()

pthread_create() 函数专门用来创建线程,语法格式如下:

1
2
3
4
5
6
7
int pthread_create(pthread_t *thread,

const pthread_attr_t *attr,

void (start_routine) (void *),

void *arg);

各个参数的含义是:

  • thread:接收一个 pthread_t 类型变量的地址,每个 pthread_t 类型的变量都可以表示一个线程。
  • attr:手动指定新线程的属性,我们可以将其置为 NULL,表示新建线程遵循默认属性。
  • start_routine:以函数指针的方式指明新建线程需要执行哪个函数。
  • arg:向 start_routinue() 函数的形参传递数据。将 arg 置为 NULL,表示不传递任何数据。

如果成功创建线程,pthread_create() 函数返回数字 0,否则返回一个非零值。各个非零值都对应着不同的宏,指明创建失败的原因,常见的宏有以下几种:

  • EAGAIN:系统资源不足,无法提供创建线程所需的资源。
  • EINVAL:传递给 pthread_create() 函数的 attr 参数无效。
  • EPERM:传递给 pthread_create() 函数的 attr 参数中,某些属性的设置为非法操作,程序没有相关的设置权限。

以上这些宏都定义在 <errno.h> 头文件中,如果想使用这些宏,需提前引入此头文件。

pthread_exit()

pthread_exit() 函数用于终止线程执行,语法格式如下:

void pthread_exit(void *retval);

retval 参数指向的数据将作为线程执行结束时的返回值,如果不需要返回任何数据,将其置为 NULL 即可。注意,retval 不能指向函数内部的局部变量,否则会导致程序运行出错甚至崩溃。

pthread_cancel()

在多线程程序中,一个线程可以借助 pthread_cancel() 函数向另一个线程发送“终止执行”的信号。

pthread_cancel() 函数的语法格式如下:

int pthread_cancel(pthread_t thread);

thread 参数用于指定接收信号的目标线程。当成功发送“终止执行”的信号时,函数返回值为 0,否则返回非零数。

pthread_join()

pthread_join() 函数的功能主要有两个,分别是:

  1. 接收目标线程执行结束时的返回值;
  2. 释放目标线程占用的进程资源。

pthead_join() 函数的语法格式如下:

int pthread_join(pthread_t thread, void ** retval);

thread 参数用于指定目标线程;retval 参数用于存储接收到的返回值。实际场景中,调用 pthread_join() 函数可能仅是为了及时释放目标线程占用的资源,并不想接收它的返回值,这种情况下可以将 retval 置为 NULL。

pthread_join() 函数会一直阻塞当前线程,直至目标线程执行结束,阻塞状态才会消除。如果成功等到了目标线程执行结束(成功获取到目标线程的返回值),pthread_join() 函数返回数字 0,否则返回非零数。

设置线程优先级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pthread_attr_t attr = { 0 };  /* 线程属性 */
struct sched_param params; /* 线程调度参数 */

/*- 配置线程属性 */
pthread_attr_init(&attr);

/*- 设置线程优先级 */
params.sched_priority = priority;

/*设置 Attr 属性的优先级为 param*/
res = pthread_attr_setschedparam(&attr, &param);

/*创建线程并遵循attr属性*/
rt = pthread_create(thread, &attr, (CM_THREAD_FUNC_T)myfunc, args);