Home c++ Working with C++ flows

Working with C++ flows

Author

Date

Category

I made synchronization of the operation of two threads created by the Example class by some super crutch method (using the test from the ID), how can I properly implement completion of 1 stream after starting 2?

That is, I create an example class an object in Main’e – & gt; The constructor starts 1 stream, which with an interval of 2 seconds displays a message with a stream ID into the console. Main stream sleep for 10 seconds, after which I launch 2 stream. Because 2 Stream is launched, I need 1 stream, waking up, immediately completed my work without performing any actions inside the cycle. Probably, theoretically correct will do it with Mutex, but I have not yet understood how.

result, if you do not add a test with ID (2 streams operate at once):

16596
16596.
16596.
16596.
16596.
9104.
16596.
9104.
16596.
9104.
16596.
9104.
16596.
9104.
16596.
9104.

Result (the one that I just needed created 2 stream no longer works in parallel with 1, because The first completed its work, stopping the cycle) with check ID:

18356
18356.
18356.
18356.
18356.
15788.
15788.
15788.
15788.
15788.
# include & lt; iostream & gt;
#Include & lt; Thread & GT;
#Include & lt; mutex & gt;
#Include & lt; atomic & gt;
#Include & lt; Chrono & gt;
Class example.
{
  STD :: Atomic_Bool M_DO_LOOP_ITERATION;
  STD :: Thread M_Thread;
  std :: mutex m_mutex;
  STD :: Atomic_int M_ID;
  Void Start ()
  {
    M_ID ++;
    m_thread = std :: thread ([& amp] ()
    {
      // STD :: LOCK_GUARD & LT; STD :: MUTEX & GT; lock (m_mutex);
      int ID = M_ID.LOAD ();
      While (do_loop_iteration ())
      {
        If (id! = M_ID.Load ())
        {
          Break;
        }
        STD :: COUT & LT; & LT; std :: this_thread :: get_id () & lt; & lt; STD :: ENDL;
        Std :: This_Thread :: Sleep_for (STD :: Chrono :: Seconds (2));
      }
    });
  }
Public:
  Example ():
    M_DO_LOOP_ITERATION (TRUE),
    M_ID (0)
  {
    start ();
  }
  BOOL DO_LOOP_ITERATION ()
  {
    RETURN M_DO_LOOP_ITERATION.LOAD ();
  }
  Void Restart ()
  {
    m_thread.detach ();
    start ();
  }
};
INT MAIN ()
{
  EXAMPLE EX;
  Std :: This_Thread :: Sleep_for (STD :: Chrono :: Seconds (10));
  EX.Restart ();
  Std :: This_Thread :: Sleep_for (STD :: Chrono :: Seconds (9999999));
  Return 0;
}

Answer 1, Authority 100%

Mutex alone allows you to block the simultaneous access of several streams to the code section. But Condition_Variable is more suitable for such a case, since it allows you to expect anything no burning crutches from Sleep or Busy Loop.

Online Compiler

# include & lt; iostream & gt;
#Include & lt; Thread & GT;
#Include & lt; mutex & gt;
#Include & lt; atomic & gt;
#Include & lt; Chrono & gt;
#include & lt; Condition_Variable & GT;
Class example.
{
  :: STD :: Thread M_Thread;
  :: std :: mutex m_mutex;
  :: STD :: CONDITION_VARIABLE M_COND;
  BOOL M_LOOP;
  int m_counter;
  Private: Void Start (Void)
  {
    M_Loop = True;
    m_thread = :: std :: thread {& amp; example :: thread_routine, this};
  }
  Private: Void Thread_Routine (Void)
  {
    :: STD :: UNIQUE_LOCK LOCK {M_MUTEX};
    do.
    {
      :: STD :: COUT & LT; & LT; M_COUNTER & LT; & LT; :: STD :: ENDL;
    }
    While
    (
      not m_cond.wait_for
      (
        lock
      , :: Std :: Chrono :: Seconds {1}
      , [this] (void)
        {
          Return NOT M_LOOP;
        }
      )
    );
  }
  Private: Void Stop (Void)
  {
    {
      :: STD :: LOCK_GUARD LOCK {M_MUTEX};
      M_loop = false;
    }
    M_COND.Notify_one ();
    m_thread.join ();
    ++ m_counter;
  } 
public: example (void): m_loop {}, m_counter {}
  {
    start ();
  }
  public: ~ example (void)
  {
    stop ();
  }
  public: void restart (void)
  {
    stop ();
    start ();
  }
};
int main ()
{
  example ex {};
  for (;;)
  {
    :: std :: this_thread :: sleep_for (:: std :: chrono :: seconds {3});
    ex.restart ();
  }
  return 0;
}

Answer 2

# include & lt; iostream & gt;
#include & lt; thread & gt;
#include & lt; mutex & gt;
#include & lt; atomic & gt;
#include & lt; chrono & gt;
#include & lt; condition_variable & gt;
class Gateway
{
  std :: thread m_thread;
  std :: condition_variable m_cond_var;
  std :: mutex m_mutex;
  std :: atomic_bool m_connected;
  void connect ();
public:
  void on_close (bool reconnect = false);
  bool is_connected () const;
  Gateway ();
  ~ Gateway ();
};
void Gateway :: connect ()
{
  std :: cout & lt; & lt; "Gateway :: connect - start" & lt; & lt; std :: endl;
  m_connected = true;
  m_thread = std :: thread ([& amp;] ()
  {
    std :: unique_lock & lt; std :: mutex & gt; lock (m_mutex);
    while (is_connected ())
    {
      std :: cout & lt; & lt; "ping" & lt; & lt; std :: this_thread :: get_id () & lt; & lt; std :: endl;
      m_cond_var.wait_for (lock, std :: chrono :: seconds (2), [& amp;] () {return not is_connected ();});
    }
  });
  std :: cout & lt; & lt; "Gateway :: connect - end" & lt; & lt; std :: endl;
}
void Gateway :: on_close (bool reconnect)
{
  std :: cout & lt; & lt; "Gateway :: on_close - start" & lt; & lt; std :: endl;
  if (is_connected ())
  {
    m_connected = false;
    m_cond_var.notify_one ();
    m_thread.join ();
  }
  if (reconnect)
    connect ();
  std :: cout & lt; & lt; "Gateway :: on_close - end" & lt; & lt; std :: endl;
}
bool Gateway :: is_connected () const
{
  return m_connected.load ();
}
Gateway :: Gateway ():
  m_connected (false)
{
  connect ();
}
Gateway :: ~ Gateway ()
{
  m_connected = false;
  m_cond_var.notify_one ();
  if (m_thread.joinable ())
    m_thread.join ();
}
int main ()
{
  std :: cout & lt; & lt; "main - start" & lt; & lt; std :: endl;
  {
    Gateway gateway;
    std :: this_thread :: sleep_for (std :: chrono :: seconds (10));
    gateway.on_close (true);
    std :: this_thread :: sleep_for (std :: chrono :: seconds (20));
  }
  std :: cout & lt; & lt; "main - end" & lt; & lt; std :: endl;
  return 0;
}

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions