线程的相关方法
方法前缀 | 相关功能 |
---|---|
pthread_ | 线程本身和各种相关函数 |
pthread_attr_ | 线程属性对象 |
pthread_mutex_ | 互斥量 |
pthread_mutexattr_ | 互斥量属性对象 |
pthread_cond_ | 条件变量 |
pthread_condattr_ | 条件变量属性对象 |
pthread_key_ | 线程数据键(Thread-specific data keys) |
线程管理(Thread management): 第一类函数直接用于线程:创建(creating),分离(detaching),连接(joining)等等。包含了用于设置和查询线程属性(可连接,调度属性等)的函数。
互斥量(Mutexes): 第二类函数是用于线程同步的,称为互斥量(mutexes),是"mutual exclusion"的缩写。
Mutex函数提供了创建,销毁,锁定和解锁互斥量的功能。同时还包括了一些用于设定或修改互斥量属性的函数。
条件变量(Condition variables):第三类函数处理共享一个互斥量的线程间的通信,基于程序员指定的条件。这类函数包括指定的条件变量的创建,销毁,等待和受信(signal)。设置查询条件变量属性的函数也包含其中。
命名约定:线程库中的所有标识符都以pthread开头
线程的创建销毁方法
pthread_create
int pthread_create(
pthread_t* __pthread_ptr, //指向线程标识符的指针,就是空的pThread对象,创建成功后就会返回有值对象
pthread_attr_t const* __attr, //用来设置线程的属性
void* (__start_routine)(void),//运行函数的起始位置
void*//运行函数的参数
);
若线程创建成功,则返回0。若线程创建失败,则返回出错编号
pthread_join
pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。
int pthread_join(pthread_t thread,
void **retval
);
参数 :thread: 线程标识符,即线程ID,标识唯一线程。retval: 用户定义的指针,用来存储被等待线程的返回值。
返回值 : 0代表成功。 失败,返回的则是错误号。
void* xunhuanxiancheng(void *arg){
char* c=(char*)arg;
LOGI("参数%s \n",c);
int i=0;
for (;i<10;i++){
LOGI("循环%d\n",i);
if(i==5){
pthread_exit(reinterpret_cast<void *>(1090000000));
}
}
return reinterpret_cast<void *>(100000222);
}
void PrintThread::runThread2() {
pthread_t tid;
pthread_create(&tid, NULL, xunhuanxiancheng, (void *) "线程!!!!");
void *status;
pthread_join(tid,&status);
LOGI("返回%d\n",(int)status);
}

pthread_detach
这个方法与pThread_join的区别就是一个是在join处等待,一个是不等待继续执行下面的代码
线程会在调用pthread_join()处等待,直到子线程消亡了才会继续往下执行。
pthread_detach使子线程进入分离状态的意思是 主线程不能再用pthread_join()和子线程同步,就是说 对子线程调用 pthread_detach之后,主线程再调用pthread_join()不会导致等待主线程阻塞等待,这时候主线程和子线程相当于两个执行序列,两者之间处于一种 分离 状态。
线程互斥锁mutex
在线程实际运行过程中,我们经常需要多个线程保持同步。这时可以用互斥锁来完成任务;互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthread_mutex_lock,pthread_mutex_unlock这几个函数以完成锁的初始化,锁的销毁,上锁和释放锁操作
功能说明 | 相关函数 |
---|---|
初始化互斥锁 | pthread_mutex_init |
使互斥锁保持一致 | pthread_mutex_consistent_np |
锁定互斥锁 | pthread_mutex_lock |
解除锁定互斥锁 | pthread_mutex_unlock |
使用非阻塞互斥锁锁定 | pthread_mutex_trylock |
销毁互斥锁 | pthread_mutex_destroy |
pthread_mutex_t mutex;
int i=0;
void* thr_fun(void* arg){
pthread_mutex_lock(&mutex);
char* no= static_cast<char *>(arg);
for(;i<5;i++){
LOGI("%s thread, i:%d\n",no,i);
sleep(1);
}
i=0;
pthread_mutex_unlock(&mutex);
return 0;
}
void PrintThread::mutexThread() {
pthread_t tid1,tid2;
pthread_mutex_init(&mutex,NULL);
pthread_create(&tid1, nullptr, thr_fun, (void *) "No1");
pthread_create(&tid2, nullptr, thr_fun, (void *) "No2");
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_mutex_destroy(&mutex);
}

条件变量cond
功能说明 | 相关函数 |
---|---|
初始化条件变量 | pthread_cond_init |
销毁条件变量 | pthread_cond_destroy |
解除等待信号 | pthread_cond_signal |
进入等待条件变量 | pthread_cond_wait |
例子:生产与消费者
//消费者数量
#define CONSUMER_NUM 2
//生产者数量
#define PRODUCER_NUM 1
pthread_t pids[CONSUMER_NUM+PRODUCER_NUM];
//产品数量
int ready=0;
//互斥锁
pthread_mutex_t mutex2;
//条件变量
pthread_cond_t has_prodect;
//生产方法
void* producer(void* arg){
int no= reinterpret_cast<int>(arg);
for (;;){
pthread_mutex_lock(&mutex2);
ready++;
LOGI("producer %d, produce product\n",ready);
//通知消费者,有新的产品可以消费了
//会阻塞输出
pthread_cond_signal(&has_prodect);
LOGI("producer %d, singal\n",no);
pthread_mutex_unlock(&mutex2);
sleep(1);
}
return 0;
}
//消费者
void* consumer(void* arg) {
int num = (int) arg;
for (;;) {
pthread_mutex_lock(&mutex2);
//while?
//superious wake ‘惊群效应’
while (ready == 0) {
//没有产品,继续等待
//1.阻塞等待has_product被唤醒
//2.释放互斥锁,pthread_mutex_unlock
//3.被唤醒时,解除阻塞,重新申请获得互斥锁pthread_mutex_lock
LOGI("%d consumer wait\n", num);
pthread_cond_wait(&has_prodect, &mutex2);
}
//有产品,消费产品
ready--;
LOGI("%d consume product\n", ready);
pthread_mutex_unlock(&mutex2);
sleep(1);
}
return 0;
}
void PrintThread::mutexThread2() {
//初始化互斥锁和条件变量
pthread_mutex_init(&mutex2,NULL);
pthread_cond_init(&has_prodect,NULL);
LOGI("init\n");
int i;
for(i=0; i<PRODUCER_NUM;i++){
//生产者线程
LOGI("%d\n",i);
pthread_create(&pids[i],NULL,producer,(void*)i);
}
for(i=0; i<CONSUMER_NUM;i++){
//消费者线程
pthread_create(&pids[PRODUCER_NUM+i],NULL,consumer,(void*)i);
}
//等待
sleep(10);
for(i=0; i<PRODUCER_NUM+CONSUMER_NUM;i++){
pthread_join(pids[i],NULL);
}
//销毁互斥锁和条件变量
pthread_mutex_destroy(&mutex2);
pthread_cond_destroy(&has_prodect);
}

网友评论