• 多线程程序的设计详解


    进程与线程:  

      进程是一个拷贝的流程,需要更大的系统开销。具有互斥性,某一进程使用着资源其他均需等待

    线程就是把一个进程分为多片,每一片都是一个独立的流程,线程相较于进程没有拷贝这些额外的系统开销。他们共享着进程的代码段、数据段,但每个线程都有属于自己的堆、栈段。所以并发程序设计师常用多线程实现!

     

    多线程程序设计基础函数:

    1)创建线程

    int pthread_create(pthread_t *restrict tidp,               //存储新创建线程的id,指针类型
                       const pthread_attr_t *restrict attr,    //创建线程的属性,一般NULL
                       void *(*start_rtn)(void),               //线程的执行函数的入口地址
                       void *restrict arg);                    //执行函数的参数,一般NULL
      Returns: 0 if OK,      error number on failure
    eg: pthread_create(&thread[0], NULL, worker1, NULL);//worker1:线程的入口函数

    2)等待线程

    int pthread_join (pthread_t thread,void **retval);//要等待线程的id  保存线程退出时的状态,一般为NULL
      Returns: 0 if OK, error number on failure
    eg: pthread_join(thread[0], NULL);

     3)退出线程

    void pthread_exit (void * retval);   //保存退出状态,一般NULL
    eg: pthread_exit(NULL); //退出线程

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    多线程互斥设计:

      实际中多线程同样具有互斥性,会同时访问同一资源->互斥锁(信号量flag)

        pthread_mutex_t mut;//定义一个互斥锁
        下列函数成功返回01)初始化互斥锁     eg: pthread_mutex_init(&mut,NULL);
    int pthread_mutex_init( pthread_mutex_t* mut, ~ attr);   //互斥锁的指针   指定互斥锁属性NULL
    2)锁住互斥锁      eg: pthread_mutex_lock(&mut);
    int pthread_mutex_lock(pthread_mutex_t* mut);             //指明需要锁住的互斥锁
    3)解开互斥锁      eg: pthread_mutex_unlock(&mut);
    int pthread_mutex_unlock(pthread_mutex_t* mut);           //指明需要解开的互斥锁

      一般多线程与互斥锁配合使用,多线程共用全局变量,每个任务函数拥有独自的堆栈,各自并行运行不打扰!

    主程序中 :        初始化互斥锁->创建多个线程(括入了线程函数)->等待多个线程结束->return 0;  此时多线程的任务函数已在后台并发运行,等待任务函数完成后程序退出;

    线程任务函数中每个线程任务函数->使用各自的堆栈空间->锁住互斥锁->共用进程所有资源->解开互斥锁->完成,退出线程;  多线程并发性的体现。

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

     多线程同步设计:

       多个线程按照规定要求的顺序来执行,即为线程同步。    设规定顺序:线程A->线程B->任务完成

    同步函数->相当于开关信号量   
    设定外部全局变量: pthread_cond_t cond_ready = PTHREAD_COND_INITIALIZER; 1)条件成熟函数 pthread_cond_signal(&cond_ready); //线程A->调用此,运行后及条件成熟 2)等待条件成熟 pthread_cond_wait(&cond_ready,&mut); //线程B->等待状态 本线程互斥锁信号量

    多线程互斥+同步函数=多线程同步

     主程序中 :        与多线程互斥相同;

    线程任务函数中:与多线程互斥前后部分相同,仅仅一个地方!锁住互斥锁->共用进程所有资源->线程条件设定,实现顺序功能->解开互斥锁->  ;

       线程A满足时,运行条件成熟函数pthread_cond_signal;线程B未等到线程A完成设定要求是,运行pthread_cond_wait一直等待。

    /*多线程互斥*/
    #include <pthread.h>
    #include <stdio.h>
    
    pthread_t thread[2];//保存线程1和2的id
    int number  = 0;
    pthread_mutex_t mut;//定义一个互斥锁
    
    void * worker1()
    {
        int i = 0;
        printf("I am worker1!
    ");
        
        for(i=0;i<10;i++)
        {
            pthread_mutex_lock(&mut);//加锁
            
            number++;
            
            pthread_mutex_unlock(&mut);//解锁
            
            printf("worker1 number is %d
    ",number);
            sleep(1);    
        }
        pthread_exit(NULL);    //退出线程
    }
    
    void * worker2()
    {
        int i = 0;
        printf("I am worker2!
    ");
        
        for(i=0;i<10;i++)
        {
            pthread_mutex_lock(&mut);//加锁
            
            number++;
            
            pthread_mutex_unlock(&mut);//解锁
            
            printf("worker2 number is %d
    ",number);
            sleep(1);    
        }
        pthread_exit(NULL);    //退出线程    
    }
    
    int main()
    {
        pthread_mutex_init(&mut,NULL);//锁的初始化,默认属性
        
        /*创建工人1线程*/
        pthread_create(&thread[0], NULL, worker1, NULL);//worker1:线程的入口函数    
        
        /*创建工人2线程*/
        pthread_create(&thread[1], NULL, worker2, NULL);
        
        /*等待工人1线程的结束*/
        pthread_join(thread[0], NULL);
        
        /*等待工人2线程的结束*/
        pthread_join(thread[1], NULL);
        
        return 0;
    }
    View Code
    /*多线程同步*/
    #include <pthread.h> 
    #include <stdio.h>
    
    pthread_t thread[2];
    int number = 0;
    pthread_mutex_t mut;
    
    pthread_cond_t cond_ready=PTHREAD_COND_INITIALIZER;
    
    void * studentA()
    {
        int i;
        
        for(i=0;i<5;i++)
        {
            pthread_mutex_lock(&mut);
            /*扫一次地*/
            number++;
            
            if (number >=5)
            {
                printf("student A has finished his work!
    ");
                /*通知B同学*/
                pthread_cond_signal(&cond_ready);
                
            }   
            pthread_mutex_unlock(&mut);
            
            /*休息1秒钟*/
            sleep(1);    
        }    
        /*退出*/
        pthread_exit(NULL);
    }
    
    void * studentB()
    {
            pthread_mutex_lock(&mut);
            
            if(number<5)/*判断A同学是否已经扫完5次地*/
                pthread_cond_wait(&cond_ready,&mut);
                
                /*拖地*/
                number = 0;
                
                pthread_mutex_unlock(&mut);
                printf("student B has finished his work!
    ");
        
        /*退出*/
        pthread_exit(NULL);    
    }
    
    int main()
    {
        /*初始化互斥锁*/
        pthread_mutex_init(&mut,NULL);
        
        /*创建A同学线程*/
        pthread_create(&thread[0], NULL, studentA, NULL);
        
        /*创建B同学线程*/
        pthread_create(&thread[1], NULL, studentB, NULL);    
        
        /*等待A同学线程结束*/
        pthread_join(thread[0], NULL); 
        
        /*等待B同学线程结束*/
        pthread_join(thread[1], NULL); 
    }
    View Code
  • 相关阅读:
    思路
    结合BeautifulSoup和hackhttp的爬虫实例
    hackhttp模板的介绍
    beauifulsoup模块的介绍
    php api_token 与 user_token 简析
    打造属于自己的火狐插件浏览器
    提高记忆力的习惯
    浏览器允许的并发请求资源数是什么意思?
    awk 进阶,百万行文件取交集
    ubuntu-docker入门到放弃(七)Dockerfile简介
  • 原文地址:https://www.cnblogs.com/hjh-666/p/11204009.html
Copyright © 2020-2023  润新知