• Linux同步互斥(Peterson算法,生产者消费者模型)


    • 同步

    两个或两个以上随时间变化的量在变化过程中保持一定的相对关系。

    • 互斥

    对一组并发进程,一次只有一个进程能够访问一个给定的资源或执行一个给定的功能。
    互斥技术可以用于解决诸如资源争用之类的冲突,还可以用于进程间的同步,使得它们可以合作。典型例子便是生产者/消费者模型。
    • 同步互斥的实现思路主要有两种:
    • 软件方法(这里讲的)
    • 信号量
    • 使用POSIX线程库(pthread_),来创建线程,管理线程,实现同步互斥。

    • POSIX(可移植操作系统)线程是线程的POSIX标准,定义了创建和操作线程的一套API。
    • 可用于多线程编程
    • POSIX线程库函数—介绍将会用到的

    • int pthread_create(pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void *), void *arg);
      •作用:创建一个线程
      •参数thread:如果创建线程成功,标识本线程的唯一标识符通过本变量返回给函数调用者;
      •参数attr:调用者通过该参数描述期望创建的线程具有什么样的属性,传入NULL表示使用默认属性;
      •参数start_routine:线程的运行实体;
      •参数arg:传递给线程实体的参数;
      •返回值:0成功,非0为错误码;
     
    • int pthread_join(pthread_t th, void **thread_return);
      •作用:等待一个线程结束,以阻塞的方式等待th指定的线程结束。
      •参数th:描述等待一个线程结束,其取值为pthread_create函数第一个参数的返回值;
      •参数thread_return:被等待线程结束时的返回值,用户定义的指针,用来存储被等待线程的返回值。
     
    • Peterson算法

    • Peterson算法是一个实现互斥的并发程序设计算法
    • 临界缓冲区问题描述

    有一个或者多个生产者产生某种类型的数据(记录、字符),并放置在缓冲区中;有一个消费者从缓冲区中取数据,每次取一项;系统保证避免对缓冲区的重复操作,也就是说,在任何时候只有一个代理(生产者或者消费者)可以访问缓冲区。
     
    • 生产者消费者模型(C代码)
    • //thread.c
      1
      #include <stdio.h> 2 #include <pthread.h> 3 #define MAX 10 //需要生产的数量 4 pthread_mutex_t the_mutex; //互斥锁 5 pthread_cond_t condc, condp; //条件变量 6 int buffer = 0;//生产者、消费者使用的缓冲区 7 8 void *producer(void *ptr) 9 { 10 int i; 11 for(i=1; i<=10; i++) 12 { 13 pthread_mutex_lock(&the_mutex); //互斥使用缓冲区 14 while(buffer !=0) pthread_cond_wait(&condp, &the_mutex); //阻塞等待 15 printf("procucer produce item %d ",i); 16 buffer = i; //生产产品 17 pthread_cond_signal(&condc);//通知消费者消费 18 pthread_mutex_unlock(&the_mutex);//释放缓冲区 19 } 20 21 pthread_exit(0); 22 23 } 24 25 void *consumer(void *ptr) 26 { 27 28 int i; 29 for(i=1; i<=10; i++) 30 { 31 pthread_mutex_lock(&the_mutex);//互斥使用缓冲区 32 while(buffer ==0) pthread_cond_wait(&condc, &the_mutex); //阻塞等待 33 printf("consumer consume item %d ",i); 34 buffer = 0;//清空缓存区 35 pthread_cond_signal(&condp);//通知生产者生产产品 36 pthread_mutex_unlock(&the_mutex);//释放缓冲区 37 } 38 pthread_exit(0); 39 40 } 41 42 int main(int argc, char *argv[]) 43 { 44 pthread_t pro, con; 45 46 pthread_mutex_init(&the_mutex, 0); //创建互斥锁 47 pthread_cond_init(&condc,0); //初始化条件变量 48 pthread_cond_init(&condp,0); 49 50 pthread_create(&con, 0, consumer, 0); 51 pthread_create(&pro, 0, producer, 0); 52 pthread_join(pro,0); 53 pthread_join(con,0); 54 pthread_cond_destroy(&condc); 55 pthread_cond_destroy(&condp); 56 pthread_mutex_destroy(&the_mutex); 57 return 0; 58 }

      输出:

    • procucer produce item 1
      consumer consume item 1
      procucer produce item 2
      consumer consume item 2
      procucer produce item 3
      consumer consume item 3
      procucer produce item 4
      consumer consume item 4
      procucer produce item 5
      consumer consume item 5
      procucer produce item 6
      consumer consume item 6
      procucer produce item 7
      consumer consume item 7
      procucer produce item 8
      consumer consume item 8
      procucer produce item 9
      consumer consume item 9
      procucer produce item 10
      consumer consume item 10

      注意:

    • 在编译中要加 -lpthread参数, 如:gcc thread.c -o thread –lpthread
    • 使用到的一些函数功能介绍
    • int pthread_cond_wait(pthread_cond_t  *cond,  pthread_mutex_t   *mutex)

      作用:互斥的条件等待,阻塞线程

      参数:*cond是指向一个条件变量的指针

        *mutex则是对相关的互斥锁的指针

    • int pthread_cond_signal(pthread_cond_t *cond)

      作用:发送一个信号给另外一个正在处于阻塞等待状态的线程,使其脱离阻塞状态,继续执行

      参数:*cond是指向一个条件变量的指针

  • 相关阅读:
    [转]怎么看工作是否到位
    [转]一个合格程序员该做的事情——你做好了吗?
    深入图解虚拟机(一)--一个问题引出的思考
    正则表达式边用边学(一)——分组、捕获
    redhat无法注册RHN的解决办法
    使用jquery扩展表格行合并方法探究
    扩展jquery easyui datagrid编辑单元格
    js点滴知识(1) -- 获取DOM对象和编码
    使用雅虎YUI Compressor压缩JS过程心得记录
    插曲一--记《数据结构与问题求解(Java语言版)(第4版)》翻译问题
  • 原文地址:https://www.cnblogs.com/dear_diary/p/6051481.html
Copyright © 2020-2023  润新知