说明:本文是在阅读《unix环境高级编程》后做的一点摘要(自己认为重要的),如果有误或不清楚的地方请参考man手册和POSIX及其他官方文档,可以的话麻烦留言指出(十分感谢)。
1、线程标识
- 线程比较
int pthread_equal(pthread_t t1, pthread_t t2); RETURN VALUE: equal returns a nonzero value; otherwise returns 0.
- 获取自身ID
pthread_t pthread_self(void);
- 线程创建
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
- 新创建的线程可以访问进程地址空间,并继承调用线程的浮点环境和信号屏蔽字,但该线程的挂起信号会被删除
- 调用失败返回错误码,不设置errno
- thread参数不能安全的传给新线程
- thread在solaris上返回的不是地址,FreeBSD返回指向线程数据结构的指针,Mac OS X的新线程地址不在一个范围,linux用无符号长整型表示(看起像指针)
2、线程终止
- 1.从启动例程返回
- 2.被同一进程中的其他线程取消
int pthread_cancel(pthread_t thread);
- 但是线程可以选择忽略被取消或者控制如何被取消,pthread_cancel仅仅提出请求
- 一个线程可以建立多个清理程序
void pthread_cleanup_push(void (*routine)(void *), void *arg); void pthread_cleanup_pop(int execute);
- 按照注册时相反的顺序执行
- routine在一下情况由pthread_cleanup_push调度
- 调用pthread_exit
- 响应取消
- 非零execute参数调用pthread_cleanup_pop
- 因为可以是宏实现,必须配对使用
- 注意直接return是不会调用的
- 3.线程调用pthread_exit
void pthread_exit(void *retval);
- 可通过下面的函数得到retval指针
int pthread_join(pthread_t thread, void **retval);
- 如果线程简单的返回,retval包含返回码
- 如果线程被取消,retval指定的内容为PTHREAD_CANCELED
- 如果线程处于游离状态,pthread_join调用会失败,返回EINVAL(与具体实现相关)
int pthread_detach(pthread_t thread);
- 可通过下面的函数得到retval指针
3、线程同步
- 1.互斥量
pthread_mutex_init(...) ...
- 2.函数pthread_mutex_timelock
pthread_mutex_timelock(pthread_mutex_t *restrict mutex, const struct timespec *restrict tsptr);
- tsptr指绝对时间
-3.读写锁(也叫共享互斥锁) - 与互斥量类似但是并行性更高(三种状态:读加锁,写加锁,不加锁)
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destory(pthread_rwlock_t *rwlock); int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
- 错误返回值针对不正确使用读写锁的情况(未初始或死锁)
- tsptr指绝对时间
4.带超时的读写锁
int pthread_rwlock_timerdlock(pthread_rwlock_t *restrict rwlock,
const struct timespec *restric tsptr);
int pthread_rwlock_timewrlock(pthread_rwlock_t *restrict rwlock,
const struct timespec *restric tsptr);
5.条件变量
- 给多个线程提供了一个会和的场所,允许线程无竞争方式等待特定条件发生
```c
int pthread_cond_init( pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
int pthread_cond_destory( pthread_cond_t *restrict cond);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restric tsptr);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
```
- 这里的超时是时间是绝对时间
6.自旋锁
- 不睡眠,忙等,在非抢占式内核中时非常有用
int pthread_spin_init(..);
int pthread_spin_destory(..);
int pthread_spin_lock(..);
int pthread_spin_trylock(..);
int pthread_spin_unlock(..);
7.屏障
- 允许每个线程等待,直到所有合作的线程都达到某一点,然后从该点继续执行
int pthread_barrier_init(..);
int pthread_barrier_destory(..);
int pthread_barrier_wait(..);
- 最后一个线程wait之后就满足了屏障计数,所有线程被唤醒
- 举例如分解堆排序