dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: How to let consumer 2 a chance to take a value?

  1. #1
    Join Date
    Dec 2010
    Posts
    907

    How to let consumer 2 a chance to take a value?

    consumer 2 never had a chance to take a value, how do I change this program to allow
    that consumer to take in some values?

    Code:
    #include "stdafx.h"
    #include <stdio.h>
    #include <iostream>
    #include <windows.h>
    #include <mutex>
    #include <deque>
    #include <condition_variable>
    #include <thread>
    #include <fstream>
    
    using namespace std;
    
    std::deque<int> q;
    std::mutex mu;
    std::condition_variable cond;
    
    class LogFile {
    	std::mutex _mu;	 
    public:
    	void shared_print(std::string id, int value) {
    		std::lock_guard<mutex> locker(_mu);
    		cout << "From " << id.c_str() << ": " << value << endl;
    	}
    };
    
    void function_1(LogFile& log) {
    	int count = 0;
    	while (count < 10) {
    		std::unique_lock<mutex> locker(mu);		 
    		//q.push_front(count);
    		log.shared_print("producder produces ", count);
    		q.push_back(count);
    		locker.unlock();
    		cond.notify_all();
    		std::this_thread::sleep_for(chrono::seconds(1));
    		count++;
    		
    	}
    }
    
    void function_2(LogFile& log) {
    	int data = 0;
    	while (data != 9) {
    		std::unique_lock<mutex> locker(mu);
    		cond.wait(locker, [](){ return !q.empty(); });
    		data = q.front();
    		q.pop_front();
    		locker.unlock();		 
    		log.shared_print("consumer 1 consumes ", data);
    	}
    }
    
    void function_3(LogFile& log) {
    	int data = 0;
    	while (data != 9) {
    		std::unique_lock<mutex> locker(mu);
    		cond.wait(locker, [](){ return !q.empty(); });
    		data = q.front();
    		q.pop_front();
    		locker.unlock();		 
    		log.shared_print("consumer 2 consumes ", data);
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    { 
    	LogFile log;
    
    	std::thread t1(function_1, std::ref(log)); 
    	std::thread t2(function_2, std::ref(log));
    	std::thread t3(function_3, std::ref(log));
    
    	
    	t1.join();
    	t2.join();
    	t3.join();
    	return 0;
    }
    Last edited by lucky6969b; October 10th, 2015 at 11:05 PM.

  2. #2
    Join Date
    Dec 2010
    Posts
    907

    Re: How to let consumer 2 a chance to take a value?

    alright,
    It works now
    Code:
    // TestConditionVariable.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <stdio.h>
    #include <iostream>
    #include <windows.h>
    #include <mutex>
    #include <deque>
    #include <condition_variable>
    #include <thread>
    #include <fstream>
    
    using namespace std;
    
    std::deque<int> q;
    std::deque<int> q2;
    std::mutex mu;
    std::condition_variable cond;
    
    class LogFile {
    	std::mutex _mu;	 
    public:
    	void shared_print(std::string id, int value) {
    		std::lock_guard<mutex> locker(_mu);
    		cout << "From " << id.c_str() << ": " << value << endl;
    	}
    };
    
    void function_1(LogFile& log) {
    	int count = 0;
    	while (count < 10) {
    		std::unique_lock<mutex> locker(mu);		 
    		//q.push_front(count);
    		log.shared_print("producder produces ", count);
    		q.push_back(count);
    		q2.push_back(count);
    		locker.unlock();
    		cond.notify_all();
    		std::this_thread::sleep_for(chrono::seconds(1));
    		count++;
    		
    	}
    }
    
    void function_2(LogFile& log) {
    	int data = 0;
    	while (data != 9) {
    		std::unique_lock<mutex> locker(mu);
    		cond.wait(locker, [](){ return !q.empty(); });
    		data = q.front();
    		q.pop_front();
    		locker.unlock();		 
    		log.shared_print("consumer 1 consumes ", data);
    	}
    }
    
    void function_3(LogFile& log) {
    	int data = 0;
    	while (data != 9) {
    		std::unique_lock<mutex> locker(mu);
    		cond.wait(locker, [](){ return !q2.empty(); });
    		data = q2.front();
    		q2.pop_front();
    		locker.unlock();		 
    		log.shared_print("consumer 2 consumes ", data);
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	//AllocConsole();
    	//freopen("CONOUT$", "w", stdout);
    	LogFile log;
    
    	std::thread t1(function_1, std::ref(log)); 
    	std::thread t2(function_2, std::ref(log));
    	std::thread t3(function_3, std::ref(log));
    
    	
    	t1.join();
    	t2.join();
    	t3.join();
    	return 0;
    }

  3. #3
    Join Date
    Dec 2010
    Posts
    907

    Re: How to let consumer 2 a chance to take a value?

    Hello,
    I got another question.
    In order to avoid spurious wake for the conditional variable.
    I want to pass the lambda function a parameter which is about the local shared queue with the producer
    But you see m_vWaypoints is a property of the "parent" object class,
    How do I pass a parameter to the lambda function in order to make up this lambda function?
    Code:
    cond.wait(locker, [](){ return !m_vWayPoints.empty(); });

  4. #4
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,603

    Re: How to let consumer 2 a chance to take a value?

    Quote Originally Posted by lucky6969b View Post
    I want to pass the lambda function a parameter which is about the local shared queue with the producer
    But you see m_vWaypoints is a property of the "parent" object class,
    How do I pass a parameter to the lambda function in order to make up this lambda function?
    Code:
    cond.wait(locker, [](){ return !m_vWayPoints.empty(); });
    Lambda Functions in C++11 - the Definitive Guide
    [] Capture nothing (or, a scorched earth strategy?)
    [&] Capture any referenced variable by reference
    [=] Capture any referenced variable by making a copy
    [=, &foo] Capture any referenced variable by making a copy, but capture variable foo by reference
    [bar] Capture bar by making a copy; don't copy anything else
    [this] Capture the this pointer of the enclosing class
    Best regards,
    Igor

  5. #5
    Join Date
    Nov 2003
    Posts
    1,902

    Re: How to let consumer 2 a chance to take a value?

    If you are going to gave 2 deque<>'s, then might as well have 2 of everything else.
    Put your deque<>/mutex/cond_var into a class with a proper interface. Then reusing multiple times is a snap.

    gg

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)