چگونگی ترکیب lock در کد c++ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

وبـــلاگ هــفت خــط کــد


آموزش های برنامه نویسی
۲۳۱ نفر آنلاین
۵۰ عضو و ۱۸۱ مهمان در سایت حاضرند

چگونگی ترکیب lock در کد c++

0 امتیاز

سلام خدمت همگی.

به کد زیر نگاه کنید:

struct Foo{
  std::mutex write_mtx; 
  std::std::vector<<int> items ;
  
  void writeOp(int value){
      std::lock_gaurd<std::mutex> lck(write_mtx);
      items_.push_back(value);
  }
  
  int searchOp(int value){
     int result =-1; 
     auto res = std::find(items.begin(),items.end(),value);
     if (res != items.end())
        result = std::distance(items.begin(),res);
        
     return result;
  }
};

متد writeOp یک mutex را lock می کنه حالا سوال اینجاست چطور باید در متذ searchOp تا زمان قفل بودن mutext توسط متذ writeOp صبر کرد؟

سوال شده خرداد 12, 1399  بوسیله ی ابید (امتیاز 781)   19 90 106

2 پاسخ

+1 امتیاز

سلام؛ برای شرط گذاشتند و منتظر ماندن آماده شدن داده در یک Thread دیگر شما باید از روش‌های Synchronization استفاده کنید. مثلاً اینجا پیشنهاد می‌کنم که از std::condition_variable استفاده کنید:

 

#include <condition_variable>
#include <iostream>
#include <chrono>
#include <vector>
#include <thread>
#include <mutex>

using namespace std::chrono_literals;

constexpr size_t a_big_chunk{1'000'000};

std::vector<char> data;
std::condition_variable condition;
std::mutex mutex;

[[noreturn]] static void worker()
{
    while (true)
    {
        std::clog << ":: " << __PRETTY_FUNCTION__ << std::endl;
        std::unique_lock l{mutex};
        condition.wait(l, [&]() { return data.size() < (a_big_chunk * .8); });

        std::clog << ":: lock worker" << std::endl;

        while (data.size() != a_big_chunk)
        {
            data.push_back(static_cast<char>(std::rand() % 255));
        }

        l.unlock();
        condition.notify_all();
        std::clog << ":: unlock worker" << std::endl;

        std::this_thread::sleep_for(500ms);
    }
}

[[noreturn]] static void consumer()
{
    while (true)
    {
        std::unique_lock l{mutex};
        condition.wait(l, [&]() { return data.size() != 0; });

        std::clog << ":: :: lock consumer" << std::endl;

        while (data.size() != 0)
        {
            data.pop_back();
        }

        std::clog << ":: :: consuming data" << std::endl;
        l.unlock();
        std::clog << ":: :: unlock consumer" << std::endl;

        std::this_thread::sleep_for(200ms);
    }
}

int main(void)
{
    std::srand(std::time(nullptr));

    std::thread(worker).detach();
    std::thread(consumer).join();
}

 

پاسخ داده شده خرداد 12, 1399 بوسیله ی mg_ramezani (امتیاز 727)   1 1 12
+1 امتیاز

از std::condition_variable استفاده کنید:

#include <iostream>
#include <vector>
#include <thread>
#include <algorithm>
#include <chrono>
using namespace std;

struct Foo{
    Foo():write_flag(false){}
    
  std::mutex write_mtx; 
  std::std::vector<<int> items ;
  std::condition_variable cv;
  std::atomic_bool write_flag;
  
  void writeOp(int value){
      write_flag = true;
      std::lock_gaurd<std::mutex> lck(write_mtx);
      items_.push_back(value);
      write_flag = false;
      cv.notify();
  }
   
  int searchOp(int value){
      {
         std::unique_lock<std::mutex> lk(m);
         c.wait(lk,[&]{return !write_flag;});
         lk.unlock();
      }
     int result =-1; 
     auto res = std::find(items.begin(),items.end(),value);
     if (res != items.end())
        result = std::distance(items.begin(),res);
         
     return result;
  }
};

 

پاسخ داده شده خرداد 13, 1399 بوسیله ی farnoosh (امتیاز 8,362)   20 44 59
ویرایش شده خرداد 13, 1399 بوسیله ی farnoosh
...