Pthreads必知必会

来源:互联网 发布:淘宝专业版退回基础版 编辑:程序博客网 时间:2024/05/18 02:22

线程VS进程:

线程优点:

  1. 线程间数据共享简单。
  2. 创建线程快于创建进程。
线程缺点:
  1. 多线程编程时,需要确保调用线程安全函数。
  2. 某个线程的bug可能会危及该进程的所有线程。
  3. 每个线程都在争用宿主进程中有限的虚拟地址空间。

线程共享属性包括:

  1. 进程ID和父进程ID。
  2. 进程组ID和会话ID。
  3. 控制终端。
  4. 进程凭证(用户ID和组ID)。
  5. 打开的文件描述符。
  6. 由fcntl()创建的记录锁(record lock)。
  7. 信号(signal)处置。
  8. 文件系统相关信息:文件权限掩码(mask)、当前工作目录和根目录。
  9. 间隔定时器(setitimer())和POSIX定时器(timer_create())。
  10. 系统V信号量撤销(undo,semadj)值。
  11. 资源限制(resource limit)。
  12. CPU时间消耗(由times()返回)。
  13. 资源消耗(由getrusage()返回)。
  14. nice值(由setpriority()和nice()设置)。
线程独有属性:
  1. 线程ID(thread ID)。
  2. 信号掩码(signal mask)。
  3. 线程特有数据。
  4. 备选信号栈(sigaltstack()).
  5. errno变量。
  6. 浮点型(floating-point)环境。
  7. 实时调度策略(real-time scheduling policy)和优先级。
  8. CPU亲和力(affinity,Linux特有)。
  9. 能力(capability,Linux特有)。
  10. 栈,本地变量和函数的调用链接(linkage)信息。
创建线程:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
void *(*start)(void *), void *arg);

终止线程:
  1. 线程start函数执行return语句并返回指定值。
  2. 线程调用pthread_exit()。
  3. 调用pthread_cancel()取消线程。
  4. 任意线程调用exit(),或者主线程执行return语句,都会导致进程中的所有线程立即终止。
void pthread_exit(void *retval);
retval所指向的内容不应该分配于线程栈中,因为线程终止后,将无法确定线程栈的内容是否有效。

获取自己的线程ID:
pthread_t pthread_self(void);

连接(joining)已经终止的线程:
int pthread_join(pthread_t thread, void **retval);
若线程并未分离(detached),则必须使用pthread_join()来进行连接。如果未能连接,那么线程终止时将产生僵尸线程。

线程的分离:
int pthread_detach(pthread_t thread);
一旦线程处于分离状态,就不能再使用pthread_join()来获取其状态,也无法使其重返“可连接”状态。

线程的同步
互斥量:防止多个线程同时访问同一共享资源。
静态互斥量
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

动态互斥量
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
如下情况,必须使用函数pthread_mutex_init(),而非静态初始化互斥量。
  1. 动态分配于堆中的互斥量。
  2. 互斥量是在栈中分配的自动变量。
  3. 初始化经由静态分配,且不适用默认属性的互斥量。
int pthread_mutex_destroy(pthread_mutex_t *mutex);

加锁和解锁互斥量
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

pthread_mutex_lock()函数的两个变体:pthread_mutex_trylock()和pthread_mutex_mutex_timedlock()。
如果互斥量已经锁定,调用pthread_mutex_trylock()失败,返回EBUSY错误。
如果参数abstime指定的时间间隔期满,而调用线程又没有获得对互斥量的所有权,那么函数pthread_mutex_timedlock()返回ETIMEDOUT错误。

互斥量类型:
PTHREAD_MUTEX_NORMAL:该类型的互斥量不具有死锁检测功能。重复加锁会导致死锁。
PTHREAD_MUTEX_ERRORCHECK:对互斥量的所有操作都会执行错误检查。运行较慢,可以作为调试工具。
PTHREAD_MUTEX_RECURSIVE:递归互斥量维护有一个锁计数器。

条件变量:允许一个线程就某个共享资源的状态变化通知其他线程,并让其他线程等待这一通知。
静态条件变量:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

动态条件变量:
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
对自动或动态分配的条件变量,或是对未采用默认属性经由静态分配的条件变量进行初始化时,必须使用pthread_cond_init()。

int pthread_cond_destroy(pthread_cond_t *cond);

通知和等待条件变量
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

0 0