Linux线程与线程控制函数-笔记

20160825

Unix环境高级编程-线程与线程控制总结

 

1.两个线程ID进行比较

函数:

#include <pthread.h>

int pthread_equal(pthread_t tid1,pthread_t tid2);

应用场景:

2.获取自身的线程ID

函数:

#include <pthread.h>

pthread_t pthread_self(void);

应用场景:

1.程序调试过程中打印线程ID有时是非常有用的。

2.用线程ID标示工作队列数据结构,线程池中不同线程通过ID识别处理队列中相同ID的工作。

3.线程的创建

函数:

#include <pthread.h>

int pthread_create(pthread_t *, const pthread_attr_t *,

void *(*start_rtn)(void), void *restrict arg);

注意:

1.主线程和新线程之间的竞争。

2.主线程不休眠,有可能新线程还没有运行之前整个进程可能就已经终止。这种特征依赖于OS中线程实现和调度算法。

3.LinuxOS使用clone系统调用来实现pthread_create,故主线程和新线程的父进程ID不同。clone创建子进程,可以共享父进程一定数量的执行环境(文件描述符和内存)。

4.线程的终止

函数:

#include <pthread.h>

int pthread_exit(void *rval_ptr);

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

注意:

进程中任一线程调用exit_exit,那么整个进程就会终止。整个进程不终止情况下结束单个线程,三种方式:

1.线程执行完,直接返回退出。

2.线程被同一进程中的其他线程取消pthread_join

3.线程调用pthread_exit

其他函数:

int pthread_cancel(pthread_t tid); /*请求控制流的非正常退出*/

void pthread_cleanup_push(void (*rtn)(void *), void *arg);/*建立线程清理处理程序*/

void pthread_cleanup_pop(int execute); /*执行线程清理处理程序*/

5.使线程进入分离状态

函数:

#include <pthread.h>

int pthread_detach(pthread_t tid);

6.线程互斥量

6.1互斥量初始化与销毁

函数:

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

注意:

1.互斥变量用pthread_mutex_t数据类型表示。

2.使用互斥变量之前,必须首先初始化,也可以把它设置为常量PTHREAD_MUTEX_INITIALIZER(只对静态分配的互斥量)

3.动态分配(malloc)互斥量,在释放内存前需要调用xxx_destroy()函数。

6.2互斥量加解锁

函数:

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

注意:

1.使用xxx_trylock线程不被阻塞,不能锁住则返回EBUSY

2.避免死锁:两个线程对两个互斥量同时加锁,如果一个线程以与另一个线程相反的顺序锁住互斥量,则才可能出现死锁,如果以相同的顺序加锁,则可避免死锁。

3.锁的粒度:太粗,多线程阻塞等待相同的锁,并发性的改善微乎其微;太细,代码变复杂,锁的开销很大。

7.线程读写锁

7.1读写锁初始化与销毁

函数:

#include <pthread.h>

int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

7.2读写锁加解锁

函数:

#include <pthread.h>

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

注意:

1.作业请求队列由单个读写锁保护,以此实现多个工作线程获取由单个主线程分配给它们的作业。示例“程序清单11-8使用读写锁”。

2.读写锁非常适合于对数据结构读的次数远大于写的情况,多个线程可以同时读,故并行性比互斥量更高。

8.线程条件变量

8.1条件变量初始化与销毁

函数:

#include <pthread.h>

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);

int pthread_cond_destroy(pthread_cond_t *cond);

注意:

1.条件变量可以用两种方式初始化:用常量PTHREAD_COND_INITIALIZER或使用pthread_cond_init函数。

8.2条件变量等待与信号

函数:

#include <pthread.h>

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *timeout);

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

注意:

1.timeout时间值是一个绝对数而不是相对数,可以使用gettimeofday获取当前时间、使用maketimeout进行时间格式转换。

2.条件变量给多个线程提供了一个会和场所。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。

应用模板:

struct msg *workq;

pthread_cond_t  qready = PTHREAD_COND_INITIALIZER;

pthread_mutex_t  qlock = PTHREAD_MUTEX_ INITIALIZER;

pthread#1{

pthread_mutex_lock(&qlock);

while (workq == NULL)

pthread_cond_wait(&qready, &qlock);

… … /*出队等等操作*/

pthread_mutex_unlock(&qlock);

}

pthread#2{

pthread_mutex_lock(&qlock);

… … /*入队等等操作*/

pthread_mutex_unlock(&qlock);

pthread_cond_signal(&qready);

}

9.线程的控制

9.1线程限制于属性

9.2线程同步属性与重入

9.3线程私有数据

9.4线程与信号、forkI/O


发布了41 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/wade_510/article/details/72084474
今日推荐