pthread是许多并行模型(OpenMP)的底层实现

pthread_once

线程的一次性初始化

1
pthread_once(pthread_once_t *once_control, void(*init_routime)(void))
  • once_control:控制变量
  • init_routime:初始化函数

将控制变量(once_control)设置为PTHREAD_ONCE_INIT即可保证在多线程编程环境中,尽管pthread_once函数会出现在多个线程中,函数也仅执行一次,究竟在哪个线程中执行由内核调度决定

pthread_create

1
2
#include <pthread.h>
pthread_create(thread, attr, start_routine, arg);
  • thread:指向线程标识符
  • 用于设置线程属性,默认也可以使用NULL
  • 线程函数地址
  • 运行函数所需要参数,可以为NULL

若创建成功,函数会返回0,若不为0则线程创建失败。

线程终止函数

int pthread_detach(pthread_t tid);

功能

  • 将线程标记为分离状态。

详细描述

  • 使得线程在终止时自动释放其资源,而不需要调用pthread_join来等待它的结束。
  • 分离线程后,不能再对该线程调用pthread_join

返回值

  • 成功时返回0
  • 失败时返回一个错误码。

使用场景

  • 当不需要等待线程完成,也不需要获取其返回值时使用。
1
2
3
pthread_t tid;
pthread_create(&tid, NULL, thread_function, NULL);
pthread_detach(tid); // 分离线程

int pthread_cancel(pthread_t tid);

功能

  • 请求取消一个线程。

详细描述

  • 向指定的线程发送一个取消请求。被请求的线程如果处于取消状态且到达一个取消点(例如在阻塞的系统调用中),则会响应取消请求并终止执行。

返回值

  • 成功时返回0
  • 失败时返回一个错误码。

使用场景

  • 当需要强制终止一个线程时使用。线程可以设置取消状态和取消类型来控制取消行为。
1
2
3
pthread_t tid;
pthread_create(&tid, NULL, thread_function, NULL);
pthread_cancel(tid); // 请求取消线程

int sched_yield(void);

功能

  • 使调用线程主动让出CPU,让其他线程可以运行。

详细描述

  • 调用线程进入就绪队列尾部,调度程序将选择其他线程运行。
  • 线程调度的一部分,用于提高系统的响应性和并发性。

返回值

  • 成功时返回0
  • 失败时返回一个错误码。

使用场景

  • 当一个线程执行了足够长时间或需要等待某些资源时,可以调用sched_yield让其他线程运行。
1
sched_yield(); // 让出CPU,让其他线程运行

int pthread_join(pthread_t tid, void **status);

功能

  • 等待指定线程终止,并获取其退出状态。

详细描述

  • 调用线程阻塞,直到指定线程终止。
  • 可以通过status参数获取被等待线程的退出状态。

返回值

  • 成功时返回0
  • 失败时返回一个错误码。

使用场景

  • 当需要等待某个线程完成其任务并获取其结果时使用。
1
2
3
4
pthread_t tid;
pthread_create(&tid, NULL, thread_function, NULL);
void *status;
pthread_join(tid, &status); // 等待线程完成并获取其退出状态

void pthread_exit(void *status);

功能

  • 终止调用线程,并返回一个退出状态。

详细描述

  • 终止当前线程的执行,并将status传递给pthread_join调用者。
  • 调用pthread_exit后,线程的资源会被释放。

返回值

  • 此函数不返回,直接终止线程。

使用场景

  • 当线程完成其任务,并希望终止并返回一个状态值时使用。
1
2
3
4
void *thread_function(void *arg) {
// 线程的工作
pthread_exit((void *)0); // 终止线程并返回状态
}

总结

函数 功能描述 使用场景
pthread_detach 将线程标记为分离状态,使其终止时自动释放资源。 不需要等待线程完成,也不需要获取其返回值时使用。
pthread_cancel 请求取消一个线程。 需要强制终止一个线程时使用。
sched_yield 使调用线程主动让出CPU,让其他线程可以运行。 当线程需要让出CPU给其他线程运行时使用。
pthread_join 等待指定线程终止,并获取其退出状态。 需要等待线程完成任务并获取其结果时使用。
pthread_exit 终止调用线程,并返回一个退出状态。 线程完成任务后,希望终止并返回一个状态值时使用。

线程的标识

pthread_t pthread_self(void)

功能

  • 获取调用线程的线程标识符。

详细描述

  • pthread_self函数返回一个表示调用线程的线程标识符(ID)。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <pthread.h>
#include <stdio.h>

void* thread_function(void* arg) {
pthread_t tid = pthread_self(); // 获取当前线程ID
printf("Thread ID: %lu\n", (unsigned long)tid);
return NULL;
}

int main() {
pthread_t tid;
pthread_create(&tid, NULL, thread_function, NULL);
pthread_join(tid, NULL);
return 0;
}

int pthread_equal(pthread_t t1, pthread_t t2)

功能

  • 比较两个线程ID是否相等。

详细描述

  • pthread_equal函数用于比较两个线程ID,如果它们相等,返回非零值(通常为1);如果它们不相等,返回0。
  • 直接使用==运算符比较pthread_t类型的线程ID在某些实现中可能不安全或不可移植,因此建议使用pthread_equal函数。

参数

  • t1:第一个线程ID。
  • t2:第二个线程ID。

返回值

  • 相等时返回非零值。
  • 不相等时返回零。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <pthread.h>
#include <stdio.h>

void* thread_function(void* arg) {
pthread_t tid = pthread_self();
printf("Thread ID: %lu\n", (unsigned long)tid);
return NULL;
}

int main() {
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, thread_function, NULL);
pthread_create(&tid2, NULL, thread_function, NULL);

pthread_join(tid1, NULL);
pthread_join(tid2, NULL);

if (pthread_equal(tid1, tid2)) {
printf("Threads are equal\n");
} else {
printf("Threads are not equal\n");
}

return 0;
}

线程的同步和互斥