多线程程序的设计详解

进程与线程:  

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

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

 

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

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!\n");
    
    for(i=0;i<10;i++)
    {
        pthread_mutex_lock(&mut);//加锁
        
        number++;
        
        pthread_mutex_unlock(&mut);//解锁
        
        printf("worker1 number is %d\n",number);
        sleep(1);    
    }
    pthread_exit(NULL);    //退出线程
}

void * worker2()
{
    int i = 0;
    printf("I am worker2!\n");
    
    for(i=0;i<10;i++)
    {
        pthread_mutex_lock(&mut);//加锁
        
        number++;
        
        pthread_mutex_unlock(&mut);//解锁
        
        printf("worker2 number is %d\n",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!\n");
            /*通知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!\n");
    
    /*退出*/
    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

 

posted @ 2019-07-17 22:09  行路人&  阅读(1945)  评论(0编辑  收藏  举报