Chinaunix首页 | 论坛 | 博客
  • 博客访问: 69923
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 420
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-27 15:04
个人简介

记录,分享

文章分类

全部博文(43)

文章存档

2017年(24)

2015年(1)

2014年(18)

我的朋友

分类: C/C++

2014-06-27 15:38:29

11.3  线程标识

#include 
int  pthread_equal( pthread_t tid1 , pthread_t  tid2);
pthread_t  pthread_self ( void );

pthread_equal 比较两个线程id。
pthread_self 返回本线程的id。

----------------------------------------------------------------------------
11.4  创建线程

#include 
int pthread_create ( pthread_t  *restrict tidp  ,  const pthread_attr_t  *restrict  attr  ,  void *(*start_rtn) (void*) , void  *restrict arg );

tidp : 函数成功返回时tidp指向新创建线程的id
attr  :  定制各种不同的线程属性
start_rtn  :  线程开始运行的入口函数
arg  :  传递给start_rtn的参数

新创建的线程继承调用线程的浮点环境以及信号屏蔽字,但该线程的未决信号集被清除。

pthread.h的函数在调用失败时会返回错误码,而不是像其他posix那样设置errno。


-----------------------------------------------------------------------------
11.5  线程终止

*

单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流
(1)线程从启动例程(start_rtn)中返回
(2)线程可以被同一进程中的其他线程取消
(3)线程调用pthread_exit。

#include 
void pthread_exit(void  *rval_ptr);

如果线程只是从它的启动例程返回,rval_ptr将包含返回值。如果线程被取消,rval_ptr指向的单元被设置为PTHREAD_CANCELED。

*

#include 
int  pthread_ join ( pthread_t  thread  ,  void  **rval_ptr );

pthread_join 阻塞调用线程以等待thread对应线程退出,通过rval_ptr获取线程thread的返回值,如果对线程的返回值不感兴趣,可将其设为NULL

通过调用pthread_join,可将线程置为分离状态,如果线程已经处于分离状态,pthread_join调用就会失败。

*

#include 
int pthread_cancel ( pthread_t tid );

pthread_cancel 函数会使得由tid标识的线程的行为表现的如同调用了参数为PTHREAD_CANCELED的pthread_exit函数。

*

#include
void  pthread_cleanup_push ( void (*rtn)(void *) , void *arg );
void pthread_cleanup_pop ( int execute );

线程可以安排它退出时需要调用的函数(线程清理处理程序),处理程序记录在栈中(执行顺序与注册顺序相反)

当线程执行以下动作时调用清理函数 ( 正常线程返回不会引起rtn的调用)
1.调用pthread_exit
2.响应pthread_cancel
3.用非0参数调用pthread_cleanup_pop

*

#include
int  pthread_detatch(pthread_t tid);

默认情况下,线程的终止状态会保存到对该线程调用pthread_join。如果线程已经处于分离状态,线程的底层存储资源可以在线程终止时立即被回收。
当线程被分离时,并不能用pthread_join等待它的终止状态。对分离状态的线程进行pthread_join调用会产生失败,返回EINVAL。
pthread_detatch调用可以用于使线程进入分离状态。


--------------------------------------------------------------------------------
11.6  线程同步

1.互斥量

互斥量用pthread_mutex_t数据类型来表示。
如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥量加锁,其他线程看到互斥量依然被锁住,只能再次等待它重新变为可用。

#include
int pthread_mutex_init ( pthread_mutex *restrict mutex , const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destory (pthread_mutex_t *mutex);

互斥量使用前必须初始化。可以把它设为常量PTHREAD_MUTEX_INITIALIZER(静态分配的互斥量),也可以通过pthread_mutex_init函数进行初始化。如果是动态分配的互斥量(如通过malloc),那么
在释放内存前需要调用pthread_mutext_destroy函数释放底层资源。
attr指定了互斥量的属性,如果要用默认属性,只需把它设为NULL。


#include
int  pthread_mutex_lock ( pthread_mutext_t  *mutex );
int  pthread_mutext_trylock ( phtread_mutext_t  *mutex );
int  pthread_mutext_unlock ( pthread_mutext_t  *mutex );

如果线程试图对同一个互斥量加锁两次,那么它自身就会陷入死锁状态。


3.读写锁

读写锁非常适合对数据结构读的次数远大于写的次数的情况。

#include 
int pthread_rwlock_init ( pthread_rwlock_t  *restrict rwlock , const pthread_rwlockattr_t  *restrict attr);
int pthread_rwlock_destroy ( pthread_rwlock_t  *restrict rwlock );

int pthread_rwlock_rdlock( pthread_rwlock_t *rwlock );
int pthread_rwlock_tryrdlock( pthread_rwlock_t *rwlock );
int pthread_rwlock_wrlock( pthread_rwlock_t *rwlock );
int pthread_rwlock_trywrlock( pthread_rwlock_t *rwlock );
int pthread_rwlock_unlock( pthread_rwlock_t *rwlock );

4.条件变量

pthread_cond_t数据类型代表条件变量。条件变量使用前必须进行初始化。可以把常量PTHREAD_COND_INITIALIZER赋给静态分配的条件变量,或者使用pthread_cond_init进行初始化。
如果是动态分配的,需要使用pthread_cond_init进行初始化,并在使用结束后用pthread_mutex_destroy释放底层的内存空间。

#include 
int pthread_cond_init ( pthread_cond_t *restrict cond , pthread_condattr_t *restrict attr );
int pthread_cond_destroy ( pthread_cond_t *cond );

条件变量本身由互斥量保护的,线程在改变条件状态前必须先锁住互斥量。其他线程在获得互斥量之前不会察觉到这种改变,因为必须锁定互斥量后才能计算条件。

#include
int pthread_cond_wait ( pthread_cond_t *restrict cond , pthread_mutex_t *restrict mutex );
int pthread_condt_timewait ( pthread_cond_t *restrict cond , pthread_mutex_t *restrict mutex , const struct timespec *restrict timeout );

struc timespec {
  time_t tv_sec;  //秒
  long tv_nsec;  //纳秒
}
timespec是个绝对数而不是相对数。比如要等待3分钟,需要把当前时间加上三分钟转换成timespec,而不是把三分钟转换成timespec。可以使用gettimeofday获取timeval结构表示的当前
时间,然后把这个时间转换成timespec结构。要得到timeout值的绝对时间,可以使用maketimeout函数。

使用pthread_cond_wait等待条件变为真,如果给定时间发内条件不满足,那么生成一个出错码返回。
传递给phtread_cond_wait的互斥量对条件进行保护,调用者把锁住的互斥量传给函数。函数把调用线程放到等待条件的线程列表上,然后对互斥量解锁,这两个操作是原子操作。这样就关闭了
条件检查和线程进入休眠状态等待条件改变这两个操作之间的时间通道。这样线程就不会错过条件的任何变化。pthread_cond_wait返回时,互斥量再次被锁住。

从pthread_cond_wait 或 pthread_cond_timewait调用成功返回时,线程需要重新计算条件,因为其他的线程可能已经在运行并改变了条件。

#include
int pthread_cond_signal ( pthread_cond_t *cond);
int pthread_cond_broadcast ( pthread_cond_t *cond);

pthread_cond_signal函数将唤醒等待该条件的某个线程,而pthread_cond_broadcast函数将唤醒等待该条件的所有线程。注意一定要在改变条件状态后在给线程发送信号。



阅读(547) | 评论(0) | 转发(0) |
0

上一篇:ch3_file_io

下一篇:ch12_thread_control

给主人留下些什么吧!~~