Pthreads编程入门

Pthreads编程入门

本文为并行程序设计导论部分第四章的总结,读者可结合书本内容一起理解

Pthreas介绍

POSIX线程(英语:POSIX Threads,常被缩写为Pthreads)是POSIX的线程标准,定义了创建和操纵线程的一套API。

Pthreads API的一套操作函数和基本数据类型包含在pthread.h头文件中,编译时通过-lpthread将Phtreads的函数链接进来。

创建与终止

pthread对象

pthread_t数据类型是用于线程的身份标识的数据结构,与线程相关的一套函数为:

pthread_t pthread_handle;

// 第一个参数为pthread_t线程标识指针;第二个参数为设定线程属性,一般设为NULL;第三个参数为线程函数;第四个为线程函数的参数
// **注意**:线程函数的声明一般为`void* func(void* arg)`的形式
int pthread_create(pthread_t* thread_p, const pthread_attr_t* attr_p, void* (*start_routine)(void*), void* arg_p);

// 线程回收函数,等待thread_p线程运行完毕
// 其中第一个参数为回收的线程对象,第二个为线程函数的返回值
int pthread_join(pthread_t thread_p, void** ret_val_p);

//线程主动退出函数
void pthread_exit(void* ret_val_p);

函数的参数为指定的线程函数退出的返回值。

线程同步

互斥锁(mutex)

pthread_mutex_t是互斥锁在Pthreads里面的数据类型声明,互斥锁对应的一套函数为:

pthread_mutex_t mutex;

// 函数的第一个参数为互斥锁类型的指针;第二个参数的功能为指定互斥锁的属性,一般为NULL
int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr_p);

// 互斥锁记得最后销毁
int pthread_mutex_destroy(pthread_mutex_t* mutex);

int pthread_mutex_lock(pthread_mutex_t* mutex);

int pthread_mutex_unlock(pthread_mutex_t* mutex);

信号量(semaphore)

信号量的API不包含在Pthread的标准头文件pthread.h中,在semaphore.h头文件中。
在linux中信号量对应的一套函数为:

sem_t semaphore;

// 信号量的初始化函数,第二个参数一般为0,第三个参数为信号量的初始化数值
int sem_init(sem_t* semaphore, int shared, unsinged initial_val);

int sem_destroy(sem_t* semaphore);

// 对信号量加一
int sem_post(sem_t* semaphore);

// 对信号量减一,如果信号量为0,则阻塞等待
int sem_wait(sem_t* semaphore);

条件变量(condition)

条件变量在Pthreads中的一套函数为:

pthread_cond_t condition;

// 条件变量的初始化函数,第二个参数一般指定为NULL
int pthread_cond_init(pthread_cond_t* condition, const pthread_condattr_t* attr_p);

int pthread_cond_destroy(pthread_cond_t* condition);

// pthread_cond_wait可能被其它情况解除阻塞,被signal和broadcast函数解除的阻塞返回值为0,其它情况解除阻塞返回值不为0
int pthread_cond_wait(pthread_cond_t* condition, pthread_mutex_t* mutex);

// 在时间abstime之前等待
int pthread_cond_timedwait(pthread_cond_t* condition, pthread_mutex_t* mutex, const struct timespec* abstime);

// 发送信号
int pthread_cond_signal(pthread_cond_t* condition);
// 发送全局信号
int pthread_cond_broadcast(pthread_cond_t* condition);

注意: pthread_cond_wait只会接受阻塞等待期间发送出来的信号。

pthread_cond_wait(pthread_cond_t* condition, pthread_mutex_t* mutex) 函数相当于:

unlock(mutex);
wait_signal(condition);
lock(mutex);
条件变量的应用场景

条件变量一般用在如下的应用场景中:

// safely examine the condition, prevent other threads from
// altering it
pthread_mutex_lock (&lock);
while ( SOME-CONDITION is false)
    pthread_cond_wait (&cond, &lock);

// Do whatever you need to do when condition becomes true
do_stuff();
pthread_mutex_unlock (&lock);

具体说明见:

  1. 请教关于 pthread condition 的使用场景
  2. 知乎问答:pthread_cond_wait为什么需要传递mutex参数 中etnlGD网友的回答

读写锁

读写锁是一个有意思的应用场景,其实也可以通过Pthreads前面所讲的几个基本内容来实现一个读写锁。读写锁主要满足以下需求:

  1. 当前线程对临界区进行写操作之前,必须阻塞到那儿,直到进入临界区的线程都退出临界区。
  2. 多个读线程可以同时进入到临界区。
  3. 读线程在进入临界区之前,必须保证写线程都退出临界区。

Pthreads中对应的读写锁的API如下:

pthread_rwlock_t rwlock;

// 第二个参数的功能为读写锁设定属性,一般为NULL
int pthread_rwlock_init(pthread_rwlock_t* rwlock, pthread_rwlockattr_t* attr_p);

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);

练习

  1. 思考读写锁存在的意义。
  2. 简单编程实现Pthread的读写锁功能。
  3. 思考信号量与条件变量的区别与联系。(针对应用场景)
  4. 动手实现线程池。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值