Pthread线程部分
1. Pthread基础API
}pthread_t: 线程id的数据类型
}pthread_t pthread_self(): 获得自身线程的id
}int pthread_equal( pthread_t th1, pthread_tth2): 比较两个线程id是否相等
}int pthread_create( pthread_t * tid, pthread_attr_t* attr, func, void* arg): 线程创建
}void pthread_exit( void*): 线程终止
}int pthread_join( pthread_t tid, void**): 本线程阻塞,等待tid线程终止
}intpthread_cancel(pthread_t tid): 请求取消同一进程中的其他线程
清理函数
◦void
pthread_cleanup_push( func, void*arg)
◦void
pthread_cleanup_pop( int execute)
清理函数的调用顺序由pthread_cleanup_push函数安排。pthread_cleanup_pop的参数为0时,清理函数将不被调用。在线程退出或被取消时调用,具体包括:
a. 调用pthread_exit退出时
b. 响应pthread_cancel取消时
c. 以非零参数调用pthread_cleanup_pop时
example:
//*清理函数*/
void cleanup( void* arg)
{
printf("cleanup:%s\n", (char*)arg);
}
void* th_f1( void* arg)
{
pthread_cleanup_push( cleanup, "thread 1 first");
pthread_cleanup_push( cleanup, "thread 1 second");
return ((void*) 1); //不调用清理函数
}
void* th_f2( void* arg)
{
pthread_cleanup_push( cleanup, "thread 2 first");
pthread_cleanup_push( cleanup, "thread 2 second");
pthread_exit ((void*) 2); //调用清理函数
}
void* th_f3( void* arg)
{
pthread_cleanup_push( cleanup, "thread 3 first");
pthread_cleanup_push( cleanup, "thread 3 second");
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
pthread_exit ((void*) 3); //不调用清理函数
}
2. Pthread同步
2.1 互斥
}互斥量: pthread_mutex_t
}int
pthread_mutex_init( pthread_mutex_t* mutex, pthread_mutexattr_t* attr) : 互斥量初始化
}int
pthread_mutex_destroy( pthread_mutex_t * mutex): 互斥量释放
}int
pthread_mutex_lock( pthread_mutex_t *): 加锁
}int
pthread_mutex_trylock( pthread_mutex_t * ): 尝试加锁
}int
pthread_mutex_unlock( pthread_mutex_t *): 释放锁
2.1.1 读写锁
}读写锁可以有三种状态:读模式下加锁状态、写模式下加锁状态、不加锁状态
}一次只有一个线程可以占有写模式的读写锁,但可以有多个线程同时占有读模式的读写锁。
}更高的并行性,适用于对数据结构的读次数远大于写次数的情况。
当读写锁是写状态时,在解锁前,所有试图对这个锁加锁的线程都会被阻塞;当读写锁是读状态时,所有试图以读模式对它加锁的线程都可以得到访问权,但如果线程希望以写模式进行加锁,则必须阻塞到所有线程都释放读锁。
}
}int
pthread_rwlock_init( pthread_rwlock_t * rwlock, pthread_rwlockattr_t * attr) :读写锁初始化
}int
pthread_rwlock_destroy( 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): 解锁
example:
读写锁
const MAX_LEN = 100000;
int* job_list;
int current;
pthread_rwlock_t job_lock;
int init()
{
current = 0;
job_list = (int*)malloc(sizeof(int)*MAX_LEN);
int err = pthread_rwlock_init(job_lock, NULL);
if(err != 0)
return err;
return 0;
}
void job_insert(int value)
{
pthread_rwlock_wrlock( job_lock ); //写模式
job[current] = value;
++current;
pthread_rwlock_unlock( job_lock );
}
void job_remove()
{
pthread_rwlock_wrlock( job_lock ); //写模式
if(current>0)
--current;
pthread_rwlock_unlock( job_lock );
}
int job_find( int value )
{
int result=-1;
pthread_rwlock_rdlock( job_lock );//读模式
//允许所有工作线程并发的搜索队列
for(int i=0; i<current; ++i)
if(job_list[i] == value)
result = i;
pthread_rwlock_unlock( job_lock );
return result;
}
2.2 条件变量
}条件变量:pthread_cond_t
}int
pthread_cond_init( pthread_cond_t* cond, pthread_condattr_t *attr) : 初始化
}int
pthread_cond_destroy( pthread_cond_t *cond): 释放锁
}int
pthread_cond_wait( pthread_cond_t*, pthread_mutex_t*): 等待条件变为真, 通过互斥量对条件进行保护。
}int
pthread_cond_timedwait( pthread_cond_t*, pthread_mutex_t *, struct timespec*timeout): 等待条件为真,设定timeout。
}int
pthread_cond_signal( pthread_cond_t*) : 通知线程条件已满足,将唤醒等待该条件的某个线程
}int
pthread_cond_broadcast( pthread_cond_t*): 唤醒等待该条件的所有线程
}pthread_cond_wait 用于阻塞当前线程,等待别的线程使用 pthread_cond_signa 或 pthread_cond_broadcast来唤醒它 。
}
}pthread_cond_signal 函数的作用是发送一个信号给另外一个正在处于阻塞等待状态的线程,使其脱离阻塞状态,继续执行 。最多只给一个线程发信号。假如有多个线程正在阻塞等待着这个条件变量的话,那么是根据各等待线程优先级的高低确定哪个线程接收到信号开始继续执行。如果各线程优先级相同,则根据等待时间的长短来确定哪个线程获得信号。
}
}某些应用,如线程池, pthread_cond_broadcast 唤醒全部线程,但我们通常只需要一部分线程去做执行任务,所以其它的线程需要继续wait.
example:
//条件变量///
pthread_cond_t init_cond;
pthread_mutex_t init_lock;
int init_count=0;
//master thread
void thread_master(int length) {
pthread_mutex_init(&init_lock, NULL);
pthread_cond_init(&init_cond, NULL);
/* Create worker threads. */
for (i = 0; i < length; i++) {
create_worker( thread_worker );
}
/* Wait for all the threads to set themselves up before returning. */
pthread_mutex_lock(&init_lock);
while (init_count < length) {
pthread_cond_wait(&init_cond, &init_lock);
}
pthread_mutex_unlock(&init_lock);
}
//worker thread
void thread_worker(void) {
pthread_mutex_lock(&init_lock);
init_count++;
pthread_cond_signal(&init_cond);
pthread_mutex_unlock(&init_lock);
}