15 Ağustos 2017 Salı

std::promise

Giriş
Şu satırı dahil ederiz.
#include <future>
Not1 : Javascript dilinde promise bir thread tarafından yapılan callback anlamındadır.
Not2: Eğer kullandığımız derleyicide std::promise yoksa, boost::promise kullanılabilir.

std::promise iki thread arasında producer/consumer ilişkisi kurmaya yarar. Bir thread yani producder std::promise aracılığıyla veriyi gönderir. Diğer thread ise yani consumer std::future aracılığıyla veriyi çeker.
The consumer end of the communication channel would use a std::future to consume the datum from the shared state, while the producer thread would use a std::promise to write to the shared state.
Veriyi gönderen taraf std::promise nesnesini kullanmak zorundadır çünkü std::future nesnesini setter metodu yoktur.
An easy way to think of it is that you can either set a future by returning a value or by using a promise. future has no set method; that functionality is provided by promise.
Copy Constructor
Şöyle yaparız.
auto promise = std::promise<int>{};
get_future metodu
Şöyle yaparız.
auto future_one = promise.get_future();
set_exception metodu
Şöyle yaparız.
boost::system::error_code ec;
promise.set_exception(std::make_exception_ptr(std::runtime_error(ec.message())));
set_value metodu
Açıklaması şöyle
Effects: Atomically stores the value r in the shared state and makes that state ready
Şöyle yaparız.
promise.set_value(1);
Basit Bir Örnek
Önce bir promise nesnesi kurulur.
std::promise<int> p;
Producer değeri atar.
p.set_value(10);
Consumer değeri future vasıtasıyla erişir.
auto f = p.get_future();
Linux'ta promise altta futex() kullanır.

Tam Bir Örnek - Thread'in Producer Olması
En sık kullanılan yöntem bu. Ana thread consumer. İkinci thread'in hesaplayacağı değeri bekler. Şöyle yaparız.
#include <future>
#include <iostream>
#include <thread>
#include <unistd.h>

int main(int argc, char **argv) {
  std::promise<void> p;
  auto f = p.get_future();

  std::thread t([&p](){
    std::cout << "Biding my time in a thread.\n";
    sleep(10);
    p.set_value();
  });

  std::cout << "Waiting.\n";
  f.wait();
  std::cout << "Done.\n";

  t.join();
  return 0;
}
Tam Bir Örnek - Thread'in Consumer Olması
Normalde thread'in producer olmasını bekleriz. Ancak bazı durumlarda tam tersi olabilir. Ana thread producer, ikinci thread ise consumer olabilir. Şöyle yaparız.
std::promise<void> p;
std::thread td1([&]() {
   p.get_future().wait();
   func();
});
...
p.set_value();

td1.join(); // Can't let p go out of scope pending the thread.
Promise Yerine Condition_Variable
Promise yerine std::condition_variable da rahatça kullanılabilir. Şöyle yaparız.
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <unistd.h>

int main(int argc, char **argv) {
  bool done = 0;
  std::mutex m;
  std::condition_variable cv;

  std::thread t([&m, &cv, &done](){
    std::cout << "Biding my time in a thread.\n";
    sleep(10);
    {
      std::lock_guard<std::mutex> lock(m);
      done = 1;
    }
    cv.notify_all();
  });

  std::cout << "Waiting.\n";
  {
    std::unique_lock<std::mutex> lock(m);
    cv.wait(lock, [&done]{ return done; });
  }
  std::cout << "Done.\n";

  t.join();
  return 0;
}










Hiç yorum yok:

Yorum Gönder