• 线程同步互斥量


    线程的最大特点是资源的共享性,但资源共享中带来了对共享资源的竞争问题;解决竞争问题的途径是保证对共享资源的互斥访问,所谓互斥访问是指一个执行单元在访问共享资源的时候,他她的指向单元被禁止访问,以保证线程之间同步进行;同步是了保证在同一个时刻只有一个线程对资源进行操作,linux下提供了多种方式来处理线程同步,最常用的是互斥锁,条件变量和信号。

    互斥量:

    互斥量用pthread_mutex_t 数据类型来表示;操作函数集如下所示:

    //该函数初始化一个互斥体变量,如果参数attr 为NULL,则互斥体变量mutex 使用默认的属性。
    int
    pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t* attr ); // 该函数用来锁住互斥体变量。如果参数mutex 所指的互斥体已经被锁住了,那么发出调用的线程将被阻塞直到其他线程对mutex 解锁。 int pthread_mutex_lock(pthread_mutex_t *mutex );
    //该函数用来锁住mutex 所指定的互斥体,但不阻塞。如果该互斥体已经被上锁,该调用不会阻塞等待,而会返回一个错误代码。 int pthread_mutex_trylock( pthread_t *mutex);

    //该函数用来对一个互斥体解锁。如果当前线程拥有参数mutex 所指定的互斥体,该调用将该互斥体解锁。 int pthread_mutex_unlock( pthread_mutex_t *mutex ); //该函数用来释放分配给参数mutex 的资源。调用成功时返回值为0, 否则返回一个非0 的错误代码。 int pthread_mutex_destroy (pthread_mutex_t *mutex );

    下面是没有用互斥的实例:

    #include <pthread.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #define FOR_COUNT 20
    int myglobal;/*全局变量,主线程和子线程共享*/
    void * thread_function(void *arg)/*线程函数*/
    {
        int i,j;
        for(i = 0; i<FOR_COUNT; i++)
        {
            j = myglobal;
            j = j+1;
            fflush(stdout);
            sleep(1);
            myglobal = j;
            printf(".");    
            printf("thrad global = %d\n",myglobal);
        }
        return NULL;
    }
    int main()
    {
        pthread_t mythread;
        int i;
        if(pthread_create(&mythread, NULL, thread_function, NULL))
        {
            printf("error creating thead.");
            abort();
        }
        /*主线程中对变量进行操作*/
        for(i=0; i < FOR_COUNT; i++)
        {
            myglobal = myglobal + 1;    
            printf("o");
            printf("main global = %d\n",myglobal);
            fflush(stdout);
            sleep(1);
        }
        if(pthread_join(mythread,NULL))
        {
            printf("error joining thread");
            abort();
        }
        printf("\n mygloabl equals %d\n", myglobal);
        exit(0);
    }

    结果如下所示:可以看出 两次程序运行的结果不一样,因为线程是并行的,不能假设调度策略;

    omain global = 19    omain global = 27
    .thrad global = 19   .thrad global = 27
    omain global = 20    omain global = 28
    .thrad global = 20   .thrad global = 29
    omain global = 21    omain global = 30
    .thrad global = 21   .thrad global = 31
    omain global = 22o    main global = 32
    .thrad global = 22   .thrad global = 33
    mygloabl equals 22     mygloabl equals 33
    

     使用互斥量(例子1):静态分配互斥量

    #include <pthread.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #define FOR_COUNT 20
    int myglobal;
    /* PTHREAD_MUTEX_INITIALIZER用于初始化静态分配的互斥量*/
    pthread_mutex_t mutext = PTHREAD_MUTEX_INITIALIZER;
    void * thread_function(void *arg)
    {
        int i,j;
        for(i = 0; i<FOR_COUNT; i++)
        {
            pthread_mutex_lock(&mutext);
            j = myglobal;
            j = j+1;
            fflush(stdout);
            myglobal = j;
            printf(".");            
            printf("thrad global = %d\n",myglobal);
            pthread_mutex_unlock(&mutext);    
            sleep(1);//等待让另外一个线程运行
        }
        return NULL;
    }
    int main()
    {
        pthread_t mythread;
        int i;
        if(pthread_create(&mythread, NULL, thread_function, NULL))
        {
            printf("error creating thead.");
            abort();
        }
        for(i=0; i < FOR_COUNT; i++)
        {
            pthread_mutex_lock(&mutext);
            myglobal = myglobal + 1;    
            printf("o");
            printf("main global = %d\n",myglobal); 
            pthread_mutex_unlock(&mutext);
            fflush(stdout);
            sleep(1);//等待让另外一个线程运行
        }
        if(pthread_join(mythread,NULL))
        {
            printf("error joining thread");
            abort();
        }
        pthread_mutex_destroy(&mutext);
        printf("\n mygloabl equals %d\n", myglobal);
        exit(0);
    }

     使用互斥量(例子2):动态分配互斥量

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    struct foo
    {
        int f_count;
        pthread_mutex_t f_lock;
    };
    struct foo * foo_alloc()
    {
        struct  foo * fp;
        if((fp = (struct  foo *)malloc(sizeof(struct foo))) != NULL)
        {
            if(pthread_mutex_init(&fp->f_lock, NULL) != 0)
            {
                free(fp);
                return NULL;
            }
            fp->f_count = 1;
        }
        return fp;
    }
    void foo_hold(struct foo * fp)
    {
        pthread_mutex_lock(&fp->f_lock);
        fp->f_count++;
        printf("thread %u,count is %d\n",(unsigned int)pthread_self(), fp->f_count);
        pthread_mutex_unlock(&fp->f_lock);
    }
    void foo_rele(struct foo *fp)
    {
      pthread_t tid = pthread_self();
      pthread_mutex_lock(&fp->f_lock);
      if(--fp->f_count == 0)
      {
          pthread_mutex_unlock(&fp->f_lock);
          pthread_mutex_destroy(&fp->f_lock);
          free(fp);
          printf("finally destory the global\n");
      }
      else
      {
         pthread_mutex_unlock(&fp->f_lock);
         printf("the thread %u doesn`t need the source\n", (unsigned int )tid);
      } 
    }
    void * pthread_fun1(void * fp)
    {
        struct foo * pfoo = (struct foo *)fp;
        foo_hold(pfoo);
        sleep(2);
        foo_rele(pfoo);
        pthread_exit(NULL);
        printf("pthread1 exit\n");
    }
    void * pthread_fun2(void *fp )
    {
        struct foo * pfoo = (struct foo *)fp;
        foo_hold(pfoo);
        sleep(1);
        foo_rele(pfoo);
        pthread_exit(NULL);
        printf("pthread2 exit\n");
    }
    int main()
    {
        int err;
        pthread_t  thread1, thread2;
        /*分配全局变量*/
        struct foo * fp;
        fp = foo_alloc();
        err = pthread_create(&thread1, NULL,pthread_fun1, (void *)fp);
        if( err != 0 )
        {
            printf("cant not create thread1:%s\n", strerror(err));
            exit(1);
        }
        err = pthread_create(&thread2, NULL,pthread_fun2, (void *)fp);
        if( err != 0 )
        {
            printf("cant not create thread1:%s\n", strerror(err));
            exit(1);
        }
        sleep(1);
        foo_rele(fp);
        /*主线程等待子线程退出*/
        if(pthread_join(thread1,NULL) == 0)
            printf("pthrad1 exit\n");
        if(pthread_join(thread2,NULL) == 0 )
            printf("pthrad2 exit\n");
        exit(0);
    }

    程序运行结果:

    thread 3079039856,count is 2
    thread 3070647152,count is 3
    the thread 3079042752 doesn`t need the source
    the thread 3070647152 doesn`t need the source
    finally destory the global
    pthrad1 exit
    pthrad2 exit
    
  • 相关阅读:
    测试流程规范系列(5):BUG提交
    测试流程规范系列(6):测试报告
    测试流程规范系列(7):测试准出
    安全测试系列(1):基本概念
    Linux系列(1):常用命令
    Linux——常用命令详解
    Ant——ant的使用
    java——XML与java对象装换
    SpringMVC——form标签的使用
    SpringMVC案例1——对User表进行CRUD操作
  • 原文地址:https://www.cnblogs.com/linengier/p/3002104.html
Copyright © 2020-2023  润新知