15-多线程互斥和同步

来源:互联网 发布:淘宝关注的主播在哪里 编辑:程序博客网 时间:2024/05/16 18:52

    • 一什么是多线程
    • 二多线程函数
    • 三多线程互斥
    • 四多线程同步
    • 五代码

注意:与进程区分开来。
线程同步:多个线程按照先后顺序执行,就像是排了队列一样,一个一个来;
线程互斥:多个线程对同个资源操作,为了保证被访问资源的原子性(一次只能有一个线程使用资源),所以要互斥。

一、什么是多线程

 *  线程就是“轻量级”的进程。 *  线程与创建它的进程共享代码段,数据段。 *  线程拥有自己独立的栈

二、多线程函数

(转)所谓最简单的多线程编程,就是通过pthread_create,pthread_join,pthread_exit 3个api实现线程的创建与终止,而创建的线程只做些简单的工作,如printf一些文字信息。
使用pthread_create,pthread_join,pthread_exit 进行多线程编程的模型如下图所示:
这里写图片描述

  1. pthread_create
//原型:int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg) /** @function :按照给定的线程属性attr,在一个进程(process)里创建一个新的线程(thread) * @param attr: *     如果attr为NULL,则内部使用默认的属性创建线程。如果在创建线程之后修改attr,则不会对已经创建的线程产生作用。 * @param thread: *     创建线程成功后,将thread id存储在thread里,返回给调用者。否则thrad的值是未定义的。 * @param start_routine: *     线程创建成功后,开始执行线程的入口函数start_routine。 * @param arg: *     调用者通过arg指定线程入口函数start_routine专用的参数指针。 * @return : *     0 创建成功返回0 *     EAGAIN 超出了系统限制,如创建的线程太多,一个进程最多创建线程个数PTHREAD_THREADS_MAX。 *     EINVAL attr 的值无效 * @note pthread_create创建线程后,线程入口函数即开始执行,不需要显示控制start_routine开始执行。 *     如果确实需要将此过程分为create和start2步来控制start_routine稍后执行, *     start_routine可以通过等待一个条件变量(condition variable)进行同步的方式实现。 * Compile and link with -pthread.例如:gcc -lphread*/ 
  1. pthread_exit
    /**
    • @function void pthread_exit(void *status)
    • 终止调用者线程,
    • @param status:
    • 通过status设置退出状态,与pthread_join配对使用
    • @return :
    • 无返回值,也不返回到其调用方。
    • @note
    • 如果调用线程尚未分离,则线程ID 和status 指定的退出状态将保持不变,直到应用程序调用pthread_join() 以等待该线程。
    • 否则,将忽略status。线程ID 可以立即回收。
      */
  2. pthread_join
    /**
    • @function int pthread_join(pthread_t thread, void **status);
    • 等待thread线程终止
    • 如果thread指代的线程还没有终止,将导致调用线程挂起,直到thread指代的线程终止为止。
    • @param thread:
    • 所等待的的终止线程
    • @param status:
    • 如果status的值不等于NULL,那么它的值是通过pthread_exit传递过来的。
    • @return :
    • 0 线程已经终止
    • ESRCH 多个线程不能等待同一个线程完成,否则仅有一个线程会成功完成。其他线程将终止,并返回ESRCH 错误。
    • EINVAL 一般表示thread是无效的参数
    • EDEADLK 检查到死锁状态
    • @note
    • 如果调用线程尚未分离,则线程ID 和status 指定的退出状态将保持不变,直到应用程序调用pthread_join() 以等待该线程。
    • 否则,将忽略status。线程ID 可以立即回收。
      */

三、多线程互斥:

1. 线程的互斥函数有:     1. 互斥函数的初始化:pthread_mutex_init();     2. 互斥函数的锁定函数pthread_mutex_lock();     3. 互斥函数的解锁函数pthread_mutex_unlock();     4. 互斥函数的销毁函数pthread_mutex_destroy()。

四、多线程同步:

1.  初始化    * pthread_cond_t cond_ready=PTHREAD_COND_INITIALIZER;2. 等待条件成熟    * pthread_cond_wait(&cond_ready, &mut);3. 设置条件成熟    * pthread_cond_signal(&cond_ready);

五、代码

/** Filename : pthread.c* Date     : 2017-04-24* Author   : Chen-nan* Description: 这个程序是测试线程的互斥访问的。即:多个线程同时对一个资源进行访问时候,为了保证所操作资源的原子性,一次只能一个线程访问。* */* #include <pthread.h>#include <unistd.h>#include <stdio.h>pthread_t pthread[2] ;int count = 0 ;pthread_mutex_t mutex ;/*线程A的函数*/void * funa( ) {    int i = 0 ;    for( i=0 ; i<10 ; ++i ) {        pthread_mutex_lock(  &mutex ) ;        ++count ;        printf( "chen is  : %d \n" , count ) ;        pthread_mutex_unlock(  &mutex ) ;    }    pthread_exit(NULL) ;} /*线程B的函数*/void * funb( ) {    int i = 0 ;    for( i=0 ; i<5 ; ++i ) {        pthread_mutex_lock(  &mutex ) ;        ++count ;        printf( "nan is  : %d \n" , count ) ;        pthread_mutex_unlock(  &mutex ) ;    }    pthread_exit(NULL) ;}int  main ( int argc , char **argv ) {    pthread_mutex_init( &mutex , NULL ) ;    /*创建线程A*/    pthread_create( &pthread[0] , NULL , funa , NULL ) ;    /*创建线程B*/    pthread_create( &pthread[1] , NULL , funb , NULL ) ;    /*等待线程A完成*/    pthread_join( pthread[0] , NULL ) ;    /*等待线程B完成*/    pthread_join( pthread[1] , NULL ) ;    return 0 ;}
/** Filename : pthread.c* Date     : 2017-04-24* Author   : Chen-nan* Description: 这个程序是测试线程的同步访问的。即:多个线程按照一定顺序先后执行。* */#include <pthread.h>#include <unistd.h>#include <stdio.h>pthread_t pthread[2] ;int count = 0 ;pthread_mutex_t mutex ;/*创建条件变量,其实就是创建一个信号,通过发送信号,唤醒其他进程。*/pthread_cond_t flag=PTHREAD_COND_INITIALIZER;/*线程A的函数*/void * funa( ) {    int i = 0 ;    for( i=0 ; i<10 ; ++i ) {        pthread_mutex_lock(  &mutex ) ;        ++count ;        printf( "chen is  : %d \n" , count ) ;        pthread_mutex_unlock(  &mutex ) ;        if( 10==count ) {            printf( "--------chen is finish .-------------\n")  ;            /*条件成熟,发送条件变量(信号)通过其他进程可以开工了*/            pthread_cond_signal(  &flag ) ;        }    }    pthread_exit(NULL) ;} /*线程B的函数*/void * funb( ) {    int i = 0 ;    pthread_mutex_lock(  &mutex ) ;    if( 10>count ) {    /*判断当前条件是否可以执行,不行就挂起等待。直到有其他线程发送信号为止。这个函数包含了一个互斥锁,进入挂起状态时会解锁(所以前面有一个互斥锁的锁定),当收到信号后就会加上互斥锁(所以后边要解锁)。*/        pthread_cond_wait( &flag  , &mutex ) ;     }     for( i=0 ; i<5 ; ++i ) {        ++count ;        printf( "nan is  : %d \n" , count ) ;        pthread_mutex_unlock(  &mutex ) ;    }    pthread_exit(NULL) ;}int  main ( int argc , char **argv ) {    pthread_mutex_init( &mutex , NULL ) ;    /*创建线程A*/    pthread_create( &pthread[0] , NULL , funa , NULL ) ;    /*创建线程B*/    pthread_create( &pthread[1] , NULL , funb , NULL ) ;    /*等待线程A完成*/    pthread_join( pthread[0] , NULL ) ;    /*等待线程B完成*/    pthread_join( pthread[1] , NULL ) ;    return 0 ;}
0 0
原创粉丝点击