美文网首页
android linux pThread使用

android linux pThread使用

作者: 月影路西法 | 来源:发表于2020-02-02 19:49 被阅读0次

线程的相关方法

方法前缀 相关功能
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);
}

输出结果.png

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);
}
mutex日志.png

条件变量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);
    }
生产与消费者输出.png

源码地址https://github.com/freedomangelly/TestPThreadApi

相关文章

网友评论

      本文标题:android linux pThread使用

      本文链接:https://www.haomeiwen.com/subject/tksqxhtx.html