线程学习篇
-
(一)线程创建
- 使用
pthread_create
函数创建线程,需要传递线程执行函数及其参数。 - 参数传递需要注意类型转换。
- 需要链接pthread库。
- 获取线程ID可以调用
pthread_self
函数。 - 线程间参数传递需要注意指针类型匹配。
- 使用
pthread_join
回收线程,它是一个阻塞函数。 -
(二)线程同步
- 临界资源指不能同时访问的资源。
- 使用互斥锁
pthread_mutex
来保护临界资源。 - 互斥锁有动态和静态两种创建方式。
- 互斥锁使用
pthread_mutex_lock
和pthread_mutex_unlock
函数来加锁和解锁。 - 死锁可以通过减少锁数量和调整锁顺序来避免。
-
(三)线程取消
- 使用
pthread_cancel
取消线程,需要线程有取消点。 - 可以设置取消状态为使能或禁止。
- 可以设置取消类型为延迟取消或异步取消。
- 线程清理可以使用
pthread_cleanup_push
和pthread_cleanup_pop
函数。 -
(四)其他线程操作
- 线程分离可以使用
pthread_detach
。 - 读写锁
pthread_rwlock
可以提高多线程执行效率。 - 销毁互斥锁使用
pthread_mutex_destroy
。 - 结束线程推荐使用
pthread_exit
。 -
(五)线程同步与通信
互斥锁
- 互斥锁用于保护临界资源,确保同一时间只有一个线程能够访问该资源。
- 使用
pthread_mutex_lock
和pthread_mutex_unlock
来加锁和解锁。 - 互斥锁可以静态初始化,也可以动态创建。
死锁
- 当两个或多个线程永久地等待对方持有的锁时,发生死锁。
- 避免死锁的方法包括减少锁的数量、按顺序获取锁等。
读写锁
- 读写锁允许同一时刻多个线程读取共享资源,但只能有一个线程写入资源。
- 使用
pthread_rwlock_rdlock
和pthread_rwlock_wrlock
进行读锁和写锁。 - 读写锁可以提高读取性能,适用于读多写少的场景。
条件变量
- 条件变量通常与互斥锁一起使用,用于复杂的线程同步场景。
- 线程可以在条件变量上等待特定条件成立,直到其他线程发出信号。
- 线程可以在条件变量上等待或被唤醒。
- 主要函数有
pthread_cond_wait
、pthread_cond_signal
、pthread_cond_broadcast
。信号量
- 信号量是一个整数变量,用于线程间的同步。
- 使用
sem_init
初始化信号量,sem_wait
和sem_post
用于P和V操作。 - 信号量是一个整数变量,用于线程间的同步。
- 信号量有两种操作:P操作(等待)和V操作(信号)。
- P操作会检查信号量值,如果大于0,则将其减1并继续执行;如果等于0,则线程会阻塞直到信号量值大于0。
- V操作会将信号量值加1,如果有线程在等待,则会唤醒一个线程。
- 主要函数有
sem_init
、sem_wait
、sem_post
、sem_destroy
。线程取消
- 使用
pthread_cancel
可以取消一个线程的执行。 - 需要设置取消状态和类型,并在线程中设置取消点。
- 线程清理函数用于在线程取消时释放资源。
- 主要函数有
pthread_cancel
、pthread_setcancelstate
、pthread_setcanceltype
。 - 取消线程需要设置取消点,通常是在阻塞系统调用中。
线程清理
- 使用
pthread_cleanup_push
和pthread_cleanup_pop
成对使用,在线程退出时自动调用清理函数。 - 线程清理允许在线程退出时自动执行清理代码。
- 主要函数有
pthread_cleanup_push
、pthread_cleanup_pop
。 - 清理函数不会在线程正常return时调用,而是在调用
pthread_exit
、取消线程或执行pthread_cleanup_pop
时调用。 -
(六)线程属性与控制
- 线程属性控制线程的栈大小、分离状态等。
- 使用
pthread_attr_init
和pthread_attr_destroy
初始化和销毁线程属性结构。 - 可以通过
pthread_attr_setdetachstate
设置线程分离状态。 - 主要函数有
pthread_attr_init
、pthread_attr_destroy
、pthread_attr_setdetachstate
、pthread_attr_getdetachstate
。 -
(七)错误处理
- 线程函数通常会返回错误码,需要检查错误码。
- 使用
strerror
可以将错误码转换为错误信息字符串。