How can I set up two objects to communicate with each other asynchronously?

Hello,

Here is what I've got so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// build: 
// clang++ -g -std=c++11 -Wall main.cpp -o main
// main.cpp
#include <iostream>
#include <thread>
#include <vector>

void pt_ssleep(const int delay);

class ioes
{
public:
      virtual void on_data(int i) = 0;
      virtual void from_oes(int i) = 0;
};

class oes : public ioes
{
public:
      oes() {}
      void on_data(int i) override;
      void from_oes(int i) override { }
};

void oes::on_data(int i)
{
      std::cout << i << std::endl;
}

class oms
{
public:
      oms() = delete;
      oms(ioes& param) : ioesobj(param) {}
      void send_data(int i);

private:
      ioes& ioesobj;
      std::vector<int> numbers;
};

void oms::send_data(int i)
{
      numbers.push_back(i);
      auto j = rand();
      ioesobj.on_data(j);
}

int main()
{
      std::cout << " --- start prototype --- " << std::endl;

      oes oesobj;
      oms omsobj(oesobj);

      for (int i=0; ; ++i)
      {
            omsobj.send_data(i);
            pt_ssleep(1);
      }

      std::cout << " --- end prototype --- " << std::endl;
      return 0;
}

void pt_ssleep(const int delay)
{
      std::this_thread::sleep_for(std::chrono::seconds(delay));
}


I need oes object to send some data back to oms object asynchronously and to insert those data into numbers container.

Can someone help me with this. Thank you.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
class ioes
{
public:
      virtual int on_data(int i) = 0;
      virtual void from_oes(int i) = 0;
};

#include <iostream>

class oes : public ioes
{
public:
      oes() {}
      int on_data(int i) override;
      void from_oes(int ) override { }
};

int oes::on_data(int i)
{
      std::cout << "from oes::on_data: " << (i + 100) << '\n' << std::flush;
      return i*i ;
}

class oms
{
public:
      oms() = delete;
      oms(ioes& param) : ioesobj(param) {}
      int send_data(int i);

private:
      ioes& ioesobj;
};

int oms::send_data(int i)
{
      return ioesobj.on_data(i);
}

#include <iostream>
#include <thread>
#include <future>
#include <functional>

void pt_ssleep(const int delay);

int main()
{
      std::cout << " --- start prototype --- " << std::endl;

      oes oesobj;
      oms omsobj(oesobj);

      for( int i = 0 ; i < 5 ; ++i )
      {
          std::cout << i << ". sending data aynchronously\n" << std::flush ;
          
          // http://en.cppreference.com/w/cpp/thread/async
          auto future = std::async( std::launch::async, &oms::send_data, std::addressof(omsobj), i+23 ) ;
          // omsobj.send_data(99);
          
          std::cout << "waiting for async operation to complete\n" << std::flush ;
          pt_ssleep(1);
          
          future.wait() ; // http://en.cppreference.com/w/cpp/thread/future/wait
          
          // http://en.cppreference.com/w/cpp/thread/future/get
          std::cout << "done. result: " << future.get() << "\n.................\n" << std::flush ;
      }
      std::cout << " --- end prototype --- " << std::endl;
}

void pt_ssleep(const int delay)
{
      std::this_thread::sleep_for(std::chrono::seconds(delay));
}

http://coliru.stacked-crooked.com/a/dd62d4b48318dcfc
Thanks JLBorges, it looks like I should start reading on C++11 threading.

I should have been more clear on what I mean by "asynchronous" but when I call oms::send_data() I do not need to get the return value from that function (those data are actually being sent into a socket).

I updated my original post and example. oms object updates it's numbers container and sends data to oes. There should be a mechanism for oes to send data back to oms and insert those data into numbers container.

Can you help with this one -- thank you.
> it looks like I should start reading on C++11 threading.
> Can you help with this one

Code examples would help only after you have read up on C++ concurrency.
'C++ Concurrency In Action: Practical Multithreading' by Anthony Williams is a good resource.
http://www.amazon.com/C-Concurrency-Action-Practical-Multithreading/dp/1933988770

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <memory>

struct ioes
{
    virtual ~ioes() = default ;
    virtual void on_data( int i ) = 0;
    virtual void from_oes( int i ) = 0;
};

std::mutex stdout_lock ;

struct cms
{
    explicit cms( ioes& oes_object ) : oes_object(oes_object) {}

    void send_data( int i )
    {
          sent_numbers.push_back(i);
          oes_object.on_data(i);
    }

    void recv_data( int i )
    {
        std::lock_guard<std::mutex> body_guard(lock) ;
        recd_numbers.push_back(i) ;
    }

    void print() const
    {
        std::cout << "sent data: " ;
        for( int v : sent_numbers ) std::cout << v << ' ' ;
        std::cout << '\n' ;

        std::cout << "recd data: " ;
        {
            std::lock_guard<std::mutex> body_guard(lock) ;
            for( int v : recd_numbers ) std::cout << v << ' ' ;
        }
        std::cout << '\n' ;
    }

    private:
        ioes& oes_object ;
        std::vector<int> sent_numbers ;
        std::vector<int> recd_numbers ;
        mutable std::mutex lock ;
};

struct oes : ioes
{
    void connect( cms* p ) { cms_object = p ; }

    void on_data( int i ) override
    {
         std::this_thread::sleep_for( std::chrono::milliseconds(100) );
         {
             std::lock_guard<std::mutex> body_guard(stdout_lock) ;
             std::cout << "oes::on_data(" << i << ")\n" << std::flush ;
         }

         from_oes( 1000 - i*i ) ;
    }

    void from_oes( int i ) override { if(cms_object) cms_object->recv_data(i) ; }

    private:
        cms* cms_object = nullptr ;
};

int main()
{
    oes oes_object ;
    cms cms_object(oes_object) ;
    auto pcms = std::addressof(cms_object) ;
    oes_object.connect(pcms) ;

    for( int i = 0 ; i < 10 ; ++i )
        std::thread( &cms::send_data, pcms, i + 10 ).detach() ;

    std::this_thread::sleep_for( std::chrono::seconds(3) );
    cms_object.print() ;
}

http://coliru.stacked-crooked.com/a/bff2e2f19f4ec3e7 (-stdlib=libc++)
Thanks a lot! I sure need the reading to understand the code and adapt it.
Registered users can post here. Sign in or register to post.