美文网首页
pthread 使用入门

pthread 使用入门

作者: 渝潼不肖生 | 来源:发表于2017-10-12 18:32 被阅读0次

    好记性不如烂笔头

    POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。Windows操作系统也有其移植版pthreads-win32

    API

    一、 Pthreads API中的函数可以非正式的划分为三大类:

    • 线程管理(Thread management): 第一类函数直接用于线程:创建(creating),分离(detaching),连接(joining)等等。包含了用于设置和查询线程属性(可连接,调度属性等)的函数。
    • 互斥量(Mutexes): 第二类函数是用于线程同步的,称为互斥量(mutexes),是"mutual exclusion"的缩写。
    • Mutex函数提供了创建,销毁,锁定和解锁互斥量的功能。同时还包括了一些用于设定或修改互斥量属性的函数。
    • 条件变量(Condition variables):第三类函数处理共享一个互斥量的线程间的通信,基于程序员指定的条件。这类函数包括指定的条件变量的创建,销毁,等待和受信(signal)。设置查询条件变量属性的函数也包含其中。
    • 命名约定:线程库中的所有标识符都以pthread开头
    Routine Prefix Functional Group
    pthread_ 线程本身和各种相关函数
    pthread_attr_ 线程属性对象
    pthread_mutex_ 互斥量
    pthread_mutexattr_ 互斥量属性对象
    pthread_cond_ 条件变量
    pthread_condattr_ 条件变量属性对象
    pthread_key_ 线程数据键(Thread-specific data keys)
    • 在API的设计中充满了不透明对象的概念,基本调用可以创建或修改不透明对象。不透明的对象可以被一些属性函数调用修改。

    例子

    一、 创建/终止线程

    创建一个文件pthreadTest1

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
     void* xc(void* arg){
               char* c=(char*)arg;
               printf("参数%s \n",c);
               int i=0;
            for (;i<10;i++){
                     printf("循环%d\n",i);
                       if(i==5){
                           pthread_exit(1090000000);
                   }
          }
                 return 100000222;
     }
    
     void main(){
             
            pthread_t tid;
            pthread_create(&tid,NULL,xc,"线程!!!!");
    
            void *status;
            pthread_join(tid,&status);
            printf("返回%d\n",(int)status);
    }
    

    编译

    gcc  pthreadTest1.c  -o  pthreadTest1  -lpthread
    

    运行

    ./pthreadTest1
    

    结果:

    参数线程!!!! 
    循环0
    循环1
    循环2
    循环3
    循环4
    循环5
    返回1090000000
    

    二、线程同步

    创建一个文件pthreadTest2

    #include <stdlib.h>                                                         
    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    
    int i = 0;
    //互斥锁
    pthread_mutex_t mutex;
    
    void* thr_fun(void* arg){
        //加锁
        pthread_mutex_lock(&mutex);
        char* no = (char*)arg;
        for(;i < 5; i++){
            printf("%s thread, i:%d\n",no,i);
            sleep(1);
        }
        i=0;
        //解锁
        pthread_mutex_unlock(&mutex);
    }
    
    void main(){
        pthread_t tid1, tid2;
        //初始化互斥锁
        pthread_mutex_init(&mutex,NULL);
    
        pthread_create(&tid1,NULL,thr_fun,"No1");
        pthread_create(&tid2,NULL,thr_fun,"No2");
    
        pthread_join(tid1,NULL);
        pthread_join(tid2,NULL);
    
        //销毁互斥锁
        pthread_mutex_destroy(&mutex);
    }
    

    运行结果

    No2 thread, i:0
    No2 thread, i:1
    No2 thread, i:2
    No2 thread, i:3
    No2 thread, i:4
    No1 thread, i:0
    No1 thread, i:1
    No1 thread, i:2
    No1 thread, i:3
    No1 thread, i:4
    
    

    三、生产消费者线程

    #include <stdlib.h>                                                      
    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    
    //消费者数量
    #define CONSUMER_NUM 2
    //生产者数量
    #define PRODUCER_NUM 1
    
    pthread_t pids[CONSUMER_NUM+PRODUCER_NUM];
    
    //产品队列
    int ready = 0;
    
    //互斥锁
    pthread_mutex_t mutex;
    //条件变量
    pthread_cond_t has_product;
    
    //生产
    void* producer(void* arg){
        int no = (int)arg;
        //条件变量
        for(;;){
            pthread_mutex_lock(&mutex);
            //往队列中添加产品
            ready++;
            printf("producer %d, produce product\n",no);
            //fflush(NULL);
            //通知消费者,有新的产品可以消费了
            //会阻塞输出
            pthread_cond_signal(&has_product);
            printf("producer %d, singal\n",no);
            pthread_mutex_unlock(&mutex);
            sleep(1);
        }
    }
    
    //消费者
    void* consumer(void* arg){
        int num = (int)arg;
        for(;;){
            pthread_mutex_lock(&mutex);
            //while?
            //superious wake ‘惊群效应’
            while(ready==0){
                //没有产品,继续等待
                //1.阻塞等待has_product被唤醒
                //2.释放互斥锁,pthread_mutex_unlock
                //3.被唤醒时,解除阻塞,重新申请获得互斥锁pthread_mutex_lock
                printf("%d consumer wait\n",num);
                pthread_cond_wait(&has_product,&mutex);
            }
            //有产品,消费产品
            ready--;
            printf("%d consume product\n",num);
            pthread_mutex_unlock(&mutex);
            sleep(1);
        }
    }
    
    
    void main(){
        //初始化互斥锁和条件变量                                                
        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&has_product,NULL);
        printf("init\n");
    
        int i;
        for(i=0; i<PRODUCER_NUM;i++){
            //生产者线程
            printf("%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(&mutex);
        pthread_cond_destroy(&has_product);
        
    }
    

    相关文章

      网友评论

          本文标题:pthread 使用入门

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