编辑
2024-06-18
代码
00

目录

1. 线程
2. 互斥量
3. 条件变量
4. 线程私有数据
5. 其他

c11 标准中增加了多线程支持

1. 线程

c
// 创建线程 typedef unsigned long int thrd_t; int thrd_create(thrd_t *__thr,thrd_start_t __func,void *__arg); /* __thr 线程id的指针 __func 接受 void * 参数的函数指针,返回值为 int 类型 __arg 传递给 __func 的参数 */ // 判断是否同一线程 int thrd_equal (thrd_t __lhs, thrd_t __rhs); // 返回当前线程 id thrd_t thrd_current (void); // 至少阻塞线程 __time_point 时间。阻塞期间线程可能会收到信号恢复执行, // 此时如果 __remaining 非空,则剩余时间会存储到 __remaining 中 int thrd_sleep (const struct timespec *__time_point, struct timespec *__remaining); // 终止当前线程,清理所有线程私有数据并释放资源。返回在 __res 中指定的值。 void thrd_exit (int __res) __attribute__ ((__noreturn__)); // 分离线程 int thrd_detach (thrd_t __thr); // 阻塞当前线程直到 __thr 线程结束。 // 如果 __res 非空,会存储 __thr 线程的返回值 int thrd_join (thrd_t __thr, int *__res); // 当前线程声明可以主动让出 cpu 资源 // 停止当前线程的执行,并由系统调度程序来决定下一个执行哪个线程。 // 系统调度程序可以选择当前线程以保持运行。 void thrd_yield (void);

2. 互斥量

c
typedef union { char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align __LOCK_ALIGNMENT; } mtx_t; // 根据 __type 创建互斥量,__mutex 会指向新建的互斥量 int mtx_init (mtx_t *__mutex, int __type); /* __type 可选值 mtx_plain 创建简单互斥量 mtx_recursive 创建可递归的互斥量(可多次加锁,也需要多次解锁) mtx_timed 创建一个支持超时的互斥量 mtx_timed | mtx_recursive 创建一个既支持超时又可递归的互斥量 */ // 销毁互斥量 void mtx_destroy (mtx_t *__mutex); // 阻塞当前线程直到获得互斥锁 int mtx_lock (mtx_t *__mutex); // 阻塞当前线程直到超时或者获得互斥锁 int mtx_timedlock (mtx_t *__restrict __mutex, const struct timespec *__restrict __time_point); // 如果 __mutex 未被加锁则对其加锁,否则直接返回 int mtx_trylock (mtx_t *__mutex); // 释放锁,会唤醒其他等待该锁的线程 int mtx_trylock (mtx_t *__mutex);

3. 条件变量

c
typedef union { char __size[__SIZEOF_PTHREAD_COND_T]; __extension__ long long int __align __LOCK_ALIGNMENT; } cnd_t; // 初始化 __cond 条件变量 int cnd_init (cnd_t *__cond); // 唤醒一个等待 __cond 条件变量的线程 int cnd_signal (cnd_t *__cond); // 唤醒等待 __cond 条件变量的所有线程 int cnd_broadcast (cnd_t *__cond); // 用条件变量 __cond 阻塞当前线程 int cnd_wait (cnd_t *__cond, mtx_t *__mutex); // 阻塞当前线程直到条件变量 __cond 被唤醒或超时 int cnd_timedwait (cnd_t *__restrict __cond, mtx_t *__restrict __mutex, const struct timespec *__restrict __time_point); // 销毁条件变量并释放所有资源 void cnd_destroy (cnd_t *__COND);

4. 线程私有数据

c
/* 线程对象 */ # define thread_local _Thread_local // 使用 thread_local 修饰全局变量,这样每个线程都会拥有一个线程私有的对象 // 对象的生命周期等于线程的生存时间 /* 线程存储 */ // 线程存储可以动态的分配和释放内存 // 创建一个新的线程私有存储key,并由 _tss_id 指向 // 如果 __destructor 非空,在线程终止时会调用该函数 // tss_dtor_t 为 void (*tss_dtor_t) (void*) 的函数指针 int tss_create (tss_t *__tss_id, tss_dtor_t __destructor); // 获取 __tss_id 标识的线程私有存储 void *tss_get (tss_t __tss_id); // 将 __tss_id 对应的值设置为 __val int tss_set (tss_t __tss_id, void *__val); // 释放 __tss_id 标识的线程私有存储 void tss_delete (tss_t __tss_id);

5. 其他

c
// __func 函数只执行一次,即使从多个线程调用 // 所有调用都必须使用相同的 __flag 参数 void call_once (once_flag *__flag, void (*__func)(void));

本文作者:letangers

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!