精华内容
下载资源
问答
  • //生产者任务 void producer() { for (int i = 1; i;i++) { cout ^th item ..." ; unique_lock<mutex> lock(buffer_res.mtx);//设置互斥锁 while(((buffer_res.write_position + 1) % buffer_size) == buffer_...

    c+11的实例

    #include <QCoreApplication>
    #include<iostream>
    #include <mutex>
    #include <condition_variable>
    #include <Windows.h>
    #include <thread>
    
    using namespace std;
    
    static const int buffer_size = 10; // 缓存大小
    static const int item_total = 100; //总共要生产 item_total个item
    
    // 缓存结构体, 使用循环队列当做缓存
    struct Buffer
    {
        int buffer[buffer_size];
        size_t read_position=0; // 当前读位置
        size_t write_position=0; // 当前写位置
        mutex mtx; // 读写互斥
        //条件变量
        condition_variable not_full;
        condition_variable not_empty;
    }buffer_res;
    
    typedef struct Buffer Buffer;
    
    //生产者任务
    void producer() {
        for (int i = 1; i<= item_total;i++) {
            cout << "prodece the " << i << "^th item ..." << endl;
            unique_lock<mutex> lock(buffer_res.mtx);//设置互斥锁
    
            while(((buffer_res.write_position + 1) % buffer_size) == buffer_res.read_position) {
                //当前缓存已经满了
                cout << "buffer is full now, producer is wating....." << endl;
                (buffer_res.not_full).wait(lock); // 等待缓存非full
            }
            // 向缓存中添加item
            (buffer_res.buffer)[buffer_res.write_position] = i;
            (buffer_res.write_position)++;
    
            // 若到达最后一个, 写位置置位0
            if (buffer_res.write_position == buffer_size)
                buffer_res.write_position = 0;
    
            (buffer_res.not_empty).notify_all();
            lock.unlock();
        }
    }
    
    //消费者任务
    void consumer()
    {
        static int cnt = 0;
        while(1) {
            Sleep(1);
            int data;
            unique_lock <mutex> lock(buffer_res.mtx);
            while (buffer_res.write_position == buffer_res.read_position)
            {   // 当前buffer 为空
                cout << "buffer is empty , consumer is waiting....." << endl;
                (buffer_res.not_empty).wait(lock);
            }
    
            data = (buffer_res.buffer)[buffer_res.read_position];
            (buffer_res.read_position)++;
    
            if (buffer_res.read_position >= buffer_size)
                buffer_res.read_position = 0;
    
            (buffer_res.not_full).notify_all();
            lock.unlock();
            cout << "consume the " << data << "^th item" << endl;
            if (++cnt == item_total)
                break;
        }
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        thread prodece(producer);
        thread consume(consumer);
        prodece.join();
        consume.join();
        getchar();
    
        return a.exec();
    }
    

    qt的实例

    #include <QCoreApplication>
    #include <QThread>
    #include <QWaitCondition>
    #include <QMutex>
     
    const qint32 DataSize=10;//能产生的最大数
    const qint32 BufferSize=4;//最大存储的数目
     
    int buffer[BufferSize];
    QWaitCondition bufferIsNotFull;
    QWaitCondition bufferIsNotEmpty;
    QMutex mutex;
     
    int usedSpace=0;
    class threadProducer:public QThread{
    public:
        void run(){
            for(int i=0;i<DataSize;++i){
                mutex.lock();//如果仓库满了,不生产,等待销费
                while (usedSpace==BufferSize) {
                    bufferIsNotEmpty.wait(&mutex);
                }
                buffer[i%4]=i+1;
                qDebug("producer:%d",buffer[i%4]);
                ++usedSpace;
                bufferIsNotEmpty.wakeAll();
                mutex.unlock();
            }
        }
    };
    class threadConsumer:public QThread{
    public:
        void run(){
           for(int i=0;i<DataSize;++i){
               mutex.lock();
               while (usedSpace==0) {
                   bufferIsNotEmpty.wait(&mutex);
               }
               qDebug("consumer:%d",buffer[i%4]);
               --usedSpace;
               bufferIsNotFull.wakeAll();
               mutex.unlock();
           }
        }
    };
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        threadConsumer consumer;
        threadProducer producer;
     
        consumer.start();
        producer.start();
     
        consumer.wait();
        producer.wait();
     
        return a.exec();
    }

     

    展开全文
  • // 产品队列 int ready=0; //互斥锁 pthread_mutex_t mutex; //条件变量 pthread_cond_t has_product;...//生产者 void * produce(void *arg){ char* name=(char*)arg; LOGI("生产 %s", name);
    #include <queue>
    #include <pthread.h>
    
    // 产品队列
    int ready=0;
    
    //互斥锁
    pthread_mutex_t  mutex;
    
    //条件变量
    pthread_cond_t has_product;
    
    std::queue<char *> queue1;
    
    //生产者
    
    void * produce(void *arg){
    
        char* name=(char*)arg;
        LOGI("生产 %s", name);
        for(;;){
            //锁住
            pthread_mutex_lock(&mutex);
            ready++;
            queue1.push(name);
            LOGI("生产者  生产 %d \n",ready);
            //发送一条解锁消息
            pthread_cond_signal(&has_product);
            //解锁
            pthread_mutex_unlock(&mutex);
            sleep(3);
        }
    }
    
    //消费者
    void* consumer(void* arg){
        char* name=(char*)arg;
        for(;;){
            pthread_mutex_lock(&mutex);
            //如果产品列表为空   继续等待不可能只有1个消费者
            while(ready==0){
                LOGI("没有产品了");
                pthread_cond_wait(&has_product,&mutex);
            }
            //加锁
            ready--;
            char * result = queue1.front();
            queue1.pop();
            LOGI("消费者 %s  剩余 %s, %d\n",name,result, ready);
            pthread_mutex_unlock(&mutex);
            sleep(1);
        }
    
    }
    void runtest(){
        pthread_mutex_init(&mutex,NULL);
    
        pthread_cond_init(&has_product,NULL);
        //线程的引用
        pthread_t tid1,tid2,tid3;
        char* name = "生产者";
        char* name1 = "消费者1";
        char* name2 = "消费者2";
            pthread_create(&tid1, NULL, produce, name);
    		pthread_create(&tid2,NULL,consumer,name1);
    		pthread_create(&tid3,NULL,consumer,name2);
    
        LOGI("开启线程");
        void *rval;
        pthread_join(tid1,&rval);
        pthread_join(tid2,&rval);
        pthread_join(tid3,&rval);
    
        LOGI("线程结束%d\n",rval);
    
    }



    运行结果:

    11-04 19:44:40.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:44:40.250 11553-11621/com.test.videoplayer I/videoplayer: 消费者 消费者1  剩余 生产者, 0
    11-04 19:44:41.250 11553-11621/com.test.videoplayer I/videoplayer: 没有产品了
    11-04 19:44:43.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:44:43.250 11553-11622/com.test.videoplayer I/videoplayer: 消费者 消费者2  剩余 生产者, 0
    11-04 19:44:44.250 11553-11622/com.test.videoplayer I/videoplayer: 没有产品了
    11-04 19:44:46.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:44:46.250 11553-11621/com.test.videoplayer I/videoplayer: 消费者 消费者1  剩余 生产者, 0
    11-04 19:44:47.250 11553-11621/com.test.videoplayer I/videoplayer: 没有产品了
    11-04 19:44:49.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:44:49.250 11553-11622/com.test.videoplayer I/videoplayer: 消费者 消费者2  剩余 生产者, 0
    11-04 19:44:50.250 11553-11622/com.test.videoplayer I/videoplayer: 没有产品了
    11-04 19:44:52.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:44:52.250 11553-11621/com.test.videoplayer I/videoplayer: 消费者 消费者1  剩余 生产者, 0
    11-04 19:44:53.250 11553-11621/com.test.videoplayer I/videoplayer: 没有产品了
    11-04 19:44:55.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:44:55.250 11553-11622/com.test.videoplayer I/videoplayer: 消费者 消费者2  剩余 生产者, 0
    11-04 19:44:56.250 11553-11622/com.test.videoplayer I/videoplayer: 没有产品了
    11-04 19:44:58.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:44:58.250 11553-11621/com.test.videoplayer I/videoplayer: 消费者 消费者1  剩余 生产者, 0
    11-04 19:44:59.250 11553-11621/com.test.videoplayer I/videoplayer: 没有产品了
    11-04 19:45:01.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:45:01.250 11553-11622/com.test.videoplayer I/videoplayer: 消费者 消费者2  剩余 生产者, 0
    11-04 19:45:02.250 11553-11622/com.test.videoplayer I/videoplayer: 没有产品了
    11-04 19:45:04.250 11553-11620/com.test.videoplayer I/videoplayer: 生产者  生产 1 
    11-04 19:45:04.250 11553-11621/com.test.videoplayer I/videoplayer: 消费者 消费者1  剩余 生产者, 0
    11-04 19:45:05.260 11553-11621/com.test.videoplayer I/videoplayer: 没有产品了


    展开全文
  • 此实例在windows 10系统上可以成功运行,可以修改一下,在linux上也可以运行,思路都是一样的。 说明:这个是个图书馆案例,默认100个座位,生产者消费者各2个线程 (修改:加锁
  • 在这个案例中使用可重入锁来实现生产者消费模型。 在这个案例中分别使用两个线程对同一个对象进行操作,实现生产一个商品消费一个商品的操作。 多线程操作的三个重要步骤: 1. 线程操作资源类 2. 判断、干活(业务...

    在这个案例中使用可重入锁来实现生产者消费模型。

    在这个案例中分别使用两个线程对同一个对象进行操作,实现生产一个商品消费一个商品的操作。
    多线程操作的三个重要步骤:

    1. 线程操作资源类
    2. 判断、干活(业务处理)、唤醒通知
    3. 严防虚假唤醒

    在资源类UserShareData中义了两个方法
    producer() 方法用于生产一个商品
    consumer()方法用于消费一个商品

    在producer() 方法遵循多线程处理的3个步骤,因为使用的加锁机制,所以基本模式是这样:

    加锁
    
    try{
       1.
       循环判断{
          await() //使当前线程加入 await() 等待队列中,并释放当锁
       }
    
       2.具体的业务操作
       
       3.唤醒通知
    
    }catch(InterruptedException e){
       异常处理
    }finally{
       释放锁
    }


    1.判断
    首先判断number是否等于0,如果number !=0 说明已经生产了商品,此时应该阻塞生产操作,在多线程操作中,判断操作必须是在循环中进行,否则会引发虚假唤醒
    在循环判断内部使用condition.await(),功能就是生产者线程加入 await() 等待队列中,并释放当锁,当其他线程调用signal()会重新请求锁。与Object.wait()类似。

    2.干活
    就是进行具体的业务处理,在这个案例中,使得number+1操作来进行模拟

    3.唤醒通知
    使用condition.signalAll();来唤醒await()等待队列中的所有线程,与Object.notifyAll()功能类似

    consumer()是消费商品操作,与producer() 方法的模式一致,只是number-1操作,故不再赘述。

    class UserShareData{
        private int number = 0;
        private Lock lock = new ReentrantLock();
    
        // 一把锁,一体两面
        private Condition condition = lock.newCondition();
    
        // 生产商品
        public void producer(){
            lock.lock();
            try{
                // 1.判断 如果number !=0 说明已经有商品了,应该阻塞生产操作,否则就允许生产
                while(number != 0){
                    condition.await();
                }
    
                // 2.干活 用增加数量模拟生产了商品
                number +=1;
                System.out.println(Thread.currentThread().getName()+"\t 生产的商品数量:"+ number);
                // 3.通知唤醒
                condition.signalAll();
    
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
    
        public void consumer(){
            lock.lock();
            try{
                // 1.判断 如果number ==0 说明已经没有商品了,应该阻塞消费操作,否则就允许消费
                while(number == 0){
                    condition.await();
                }
    
                // 2.干活 用减少数量模拟消费了商品
                number -=1;
                System.out.println(Thread.currentThread().getName()+"\t 消费的商品数量:"+ number);
    
                // 3.通知唤醒
                condition.signalAll();
    
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
    
        }
    
    }

    测试类:

    public class ProducerConsumerDemo_v2 {
        public static void main(String[] args) {
            UserShareData data = new UserShareData();
            new Thread( ()->{
                for (int i = 1; i < 10; i++) {
                    data.producer();
                }
            } ,"生产者").start();
    
            new Thread( ()->{
                for (int i = 1; i < 10; i++) {
                    data.consumer();
                }
            } ,"消费者").start();
    
        }
    }

    运行结果:

    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0
    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0
    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0
    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0
    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0
    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0
    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0
    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0
    生产者	 生产的商品数量:1
    消费者	 消费的商品数量:0

    可以看到有10对生产者 + 消费者的提示。
    在资源类的producer()和consumer()中都使用到了循环判断,为何会如此呢,看看jdk1.8原版中的描述:

    As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop: 

    synchronized (obj) {
     while (<condition does not hold>)
    	 obj.wait();
     ... // Perform action appropriate to condition
    }
    

    可是试着吧这俩方法中的while修改成if,然后使用2个生产者线程和2个消费者线程,得到的某次允运行结果如下:
     

    生产者1	 生产的商品数量:1
    消费者1	 消费的商品数量:0
    生产者1	 生产的商品数量:1
    消费者2	 消费的商品数量:0
    消费者1	 消费的商品数量:-1
    消费者1	 消费的商品数量:-2
    消费者1	 消费的商品数量:-3
    消费者1	 消费的商品数量:-4
    消费者1	 消费的商品数量:-5
    消费者1	 消费的商品数量:-6
    消费者1	 消费的商品数量:-7
    消费者1	 消费的商品数量:-8
    生产者1	 生产的商品数量:-7
    消费者2	 消费的商品数量:-8
    消费者2	 消费的商品数量:-9
    消费者2	 消费的商品数量:-10
    消费者2	 消费的商品数量:-11
    消费者2	 消费的商品数量:-12
    消费者2	 消费的商品数量:-13
    消费者2	 消费的商品数量:-14
    消费者2	 消费的商品数量:-15
    生产者2	 生产的商品数量:-14
    生产者1	 生产的商品数量:-13
    生产者2	 生产的商品数量:-12
    生产者1	 生产的商品数量:-11
    生产者2	 生产的商品数量:-10
    生产者1	 生产的商品数量:-9
    生产者2	 生产的商品数量:-8
    生产者1	 生产的商品数量:-7
    生产者2	 生产的商品数量:-6
    生产者1	 生产的商品数量:-5
    生产者2	 生产的商品数量:-4
    生产者1	 生产的商品数量:-3
    生产者2	 生产的商品数量:-2

    这个问题的根源就是在于产生了虚假唤醒,当恢复使用while判断之后测试正常,因此在线程中判断条件时必须使用循环判断。

    展开全文
  • 线程间通信:生产者消费者(都要加锁,且为同一把锁)

    多个线程都要加锁,并且加的是同一把锁

    public classStudent {

       Stringname;

       int age;

    }

     

    public classSetThread implementsRunnable {

     

       private Student s;

       private int x = 0;

     

       public SetThread(Student s) {

          this.s = s;

       }

     

       @Override

       public void run() {

          while (true) {

             synchronized (s) {

                if (x % 2 == 0) {

                    s.name = "林青霞";//刚走到这里,就被别人抢到了执行权

                    s.age = 27;

                }else{

                    s.name = "刘意"; //刚走到这里,就被别人抢到了执行权

                    s.age = 30;

                }

                x++;

             }

          }

       }

    }

     

    public classGetThread implementsRunnable {

       private Student s;

     

       public GetThread(Student s) {

          this.s = s;

       }

     

       @Override

       public void run() {

          while (true) {

             synchronized (s) {

                System.out.println(s.name + "---" + s.age);

             }

          }

       }

    }

     

    /*

     * 分析:

     *    资源类:Student

     *    设置学生数据:SetThread(生产者)

     *    获取学生数据:GetThread(消费者)

     *    测试类:StudentDemo

     *

     * 问题1:按照思路写代码,发现数据每次都是:null---0

     * 原因:我们在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个

     * 如何实现呢?

     *    在外界把这个数据创建出来,通过构造方法传递给其他的类。

     *

     * 问题2:为了数据的效果好一些,我加入了循环和判断,给出不同的值,这个时候产生了新的问题

     *    A:同一个数据出现多次

     *    B:姓名和年龄不匹配

     * 原因:

     *    A:同一个数据出现多次

     *        CPU的一点点时间片的执行权,就足够你执行很多次。

     *    B:姓名和年龄不匹配

     *        线程运行的随机性

     * 线程安全问题:

     *    A:是否是多线程环境     

     *    B:是否有共享数据   

     *    C:是否有多条语句操作共享数据  

     * 解决方案:

     *    加锁。

     *    注意:

     *        A:不同种类的线程都要加锁。

     *        B:不同种类的线程加的锁必须是同一把。

     */

    public classStudentDemo {

       public static void main(String[] args) {

          //创建资源

          Students = newStudent();

         

          //设置和获取的类

          SetThreadst = newSetThread(s);

          GetThreadgt = newGetThread(s);

     

          //线程类

          Threadt1 = newThread(st);

          Threadt2 = newThread(gt);

     

          //启动线程

          t1.start();

          t2.start();

       }

    }

    展开全文
  • import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock;... * 生产者消费者 * Lock接口:出现替代了同步代码块或者同步函数,将同步的隐式锁操作变成现实锁操作, *
  • * 生产者消费者 * * */class Resrouce { private String name; private int count=1; private boolean flag=false; public synchronized void set(String name) { while(flag) try{th
  • 现在需求里面,锁太拉低性能了。 所以想看看有木有不需要锁的生产者消费者队列。 在网上搜索,发现都用的ringbuffer那样的循环队列。 可是怎么看怎么都不安全啊。
  • queue队列lock、condition加锁,解锁,阻塞机制,生产者消费者关系 queue队列lock、condition加锁,解锁,阻塞机制,生产者消费者关系 1、队列的属性 from queue import Queue """ 初始化Queue(maxsize)...
  • Java多种方式解决生产者消费者问题(十分详细)

    万次阅读 多人点赞 2018-08-16 08:40:50
    生产者消费者问题 一、问题描述 生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。生产者生成一定量的数据放到缓冲区中,...
  • 生产者消费者问题的几种实现

    千次阅读 2017-05-21 20:12:58
    Semaphore实现生产者消费者模型生产者消费者问题是一个经典的问题,一般情况下都会使用synchronized关键字来对生产和消费逻辑进行加锁 ,最近学习了下并发编程相关的基础知识,尝试使用其它的几种方法来实现生产者...
  • public class Consumer implements Runnable { private WareHouse wareHouse; public Consumer(WareHouse wareHouse){ this.wareHouse = wareHouse; } @Override public void run() { ...}
  • 需求:一生产者线程读取指定文件,多个消费者线程将读取的文件写入到指定文件中,确保生产者产生的...3、使用关键字synchronized对队列加锁,当队列为空时,消费者停止消费,当队列数据长度达到指定容量时,生产者停...
  • 生产者消费者问题

    2017-02-20 20:15:13
    生产者消费者模型:在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产...
  • 两个线程一个生产者个一个消费者需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用标记或...
  • Linux实现生产者消费者模型

    万次阅读 2017-06-01 11:35:03
    生产者消费者模型 简单来说就是“321原则(并非某一规则,而是为了理解生产者消费者模型)” “3”代表的是三种关系 生产者与消费者的互斥与同步关系 生产者与生产者的互斥(或竞争)关系 消费者与消费者的...
  • 生产者消费者模型java实现

    万次阅读 2018-09-12 10:33:45
    做题的时候遇到了生产者消费者问题,这个问题可以说是线程学习的经典题目了,就忍不住研究了一波。它描述是有一块缓冲区(队列实现)作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。在Java中这...
  • 生产者消费者模式

    2021-07-02 16:02:23
    生产者消费者模式产品商店注:生产者消费者测试 产品 商店 注: 使用wait()时,一定要加锁(synchronized),否则会报错 生产者 消费者 测试
  • 【操作系统】生产者消费者问题

    万次阅读 多人点赞 2018-08-11 00:43:20
    生产者消费者模型 生产者消费者模型 一、 生产者消费者问题 二、 问题分析 三、 伪代码实现 四、代码实现(C++) 五、 互斥锁与条件变量的使用比较 一、 生产者消费者问题 生产者消费者问题...
  • 文章目录生产者消费者模型什么是生产者消费者模型生产者消费者模型的321原则生产者消费者模型的优点生产者消费者模型的实现方法基于循环队列,信号量实现基于阻塞队列,互斥锁、条件变量实现 生产者消费者模型 什么...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,040
精华内容 12,016
关键字:

生产者消费者加锁