-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexample.cpp
147 lines (126 loc) · 4.41 KB
/
example.cpp
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "ipc.h"
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <thread>
#include <string>
/**
* This program is a simple example of the shared memory
* wrappers defined in "ipc.h".
*/
// A simple shared memory object
struct employee
{
// boost::interprocess::string required
ipc::string _name;
int _empNum;
};
//
struct SC : public ipc::SharedMemory
{
// Construct this object, creating all the shared
// memory objects. This is the "server".
SC(unsigned int size)
: ipc::SharedMemory("EMP_SEGMENT", size),
_vector(10, "EMP_VECTOR", _segment),
_map("EMP_MAP", _segment, true),
_mtx("EMP_MTX", _segment, true)
{
}
// Construct this object, initialize references to
// existing shared memory objects. This is the "client".
SC()
: ipc::SharedMemory("EMP_SEGMENT"),
_vector("EMP_VECTOR", _segment),
_map("EMP_MAP", _segment, false),
_mtx("EMP_MTX", _segment, false)
{
}
void show()
{
// Lock while reading, note we used a recursive mutex
bip::scoped_lock<bip::interprocess_recursive_mutex> lock(_mtx.reference());
// Use the reference() method in range based for loops
std::cerr << "\nvector: ";
for (auto& e : _vector.reference())
{
std::cerr << "(" << e._name.c_str() << " " << e._empNum << ") ";
}
std::cerr << "\n";
// Showing that you can use the objects as a pointer
auto p = _map->begin();
auto end = _map->end();
std::cerr << "map: ";
while (p != end)
{
std::cerr << "[" << p->first << "]=" << p->second << " ";
++p;
}
std::cerr << "\n\n";
}
ipc::SharedMap<ipc::string, int> _map;
ipc::SharedVector<employee> _vector;
ipc::SharedMutex<bip::interprocess_recursive_mutex> _mtx;
};
int main(int argc, char* argv[])
{
// Run the program with no arguments for the "server", and with
// one (or more) arguments to be a "client". Note: if you kill
// the server before the client, bad things happen.
if (argc == 1)
{
std::cout << "In parent" << std::endl;
SC sm(65536);
int num = 1000;
auto aa = sm.getAllocator<char>();
// Add an initial element to the vector and map
sm._vector->push_back({ipc::string("Assad", aa), num});
sm._map->insert(std::pair<ipc::string, int>(ipc::string("Assad", aa), num++));
for (auto& n : {"Putin", "Kim", "Hillary", "Jong", "Obama", "Un", "Comey" })
{
// Give your peers a chance to acquire the lock
std::this_thread::sleep_for(std::chrono::microseconds(1));
// Acquire the lock
bip::scoped_lock<bip::interprocess_recursive_mutex> lock(sm._mtx.reference());
// Show what we've got so far
sm.show();
// Ask for user input while holding to lock to block the client from reading
std::cout << "Enter zero to terminate: ";
int input = 0;
std::cin >> input;
if (input == 0) break;
// The operator->() is overloaded in SharedVector and SharedMap so
// the full boost objects API is available using pointer semantics
sm._vector->push_back({ipc::string(n, aa), num});
sm._map->insert(std::pair<ipc::string, int>(ipc::string(n, aa), num++));
}
for (auto& e : sm._vector.reference())
{
std::cerr << e._name.c_str() << " ";
}
std::cerr << "\n";
}
else
{
std::cout << "In child" << std::endl;
SC sm;
while (true)
{
// Give your peers a chance to acquire the lock
std::this_thread::sleep_for(std::chrono::microseconds(1));
// Acquire the lock
bip::scoped_lock<bip::interprocess_recursive_mutex> lock(
sm._mtx.reference());
sm.show();
// Grab the top vector element and add a "client" version
auto e = sm._vector->back();
std::string n = e._name.c_str();
n += "-client";
auto aa = sm.getAllocator<char>();
sm._vector->push_back({ipc::string(n.c_str(), aa), e._empNum});
sm._map->insert(
std::pair<ipc::string, int>(ipc::string(n.c_str(), aa), e._empNum));
}
}
return 0;
};