1 | // Copyright (C) 2014 Vicente Botet |
2 | // |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5 | |
6 | #include <boost/interprocess/shared_memory_object.hpp> |
7 | #include <boost/interprocess/mapped_region.hpp> |
8 | #include <boost/thread.hpp> |
9 | |
10 | using namespace boost::interprocess; |
11 | |
12 | struct item |
13 | { |
14 | int i; |
15 | }; |
16 | |
17 | struct queue |
18 | { |
19 | void put( const item& item ) |
20 | { |
21 | boost::unique_lock<boost::mutex> lock(mutex); |
22 | while ( item_in ) |
23 | cond_full.wait(m&: lock); |
24 | |
25 | item_ = item; |
26 | item_in = true; |
27 | cond_empty.notify_one(); |
28 | } |
29 | |
30 | void print() |
31 | { |
32 | boost::unique_lock<boost::mutex> lock(mutex); |
33 | while ( !item_in ) |
34 | cond_empty.wait(m&: lock); |
35 | |
36 | item_in = false; |
37 | std::cout << item_.i << std::endl; |
38 | cond_full.notify_one(); |
39 | } |
40 | |
41 | |
42 | private: |
43 | //Mutex to protect access to the queue |
44 | boost::mutex mutex; |
45 | |
46 | //Condition to wait when the queue is empty |
47 | boost::condition_variable cond_empty; |
48 | |
49 | //Condition to wait when the queue is full |
50 | boost::condition_variable cond_full; |
51 | |
52 | bool item_in; |
53 | |
54 | //Items to fill |
55 | item item_; |
56 | }; |
57 | |
58 | void *addr; |
59 | |
60 | void printThread() |
61 | { |
62 | //Erase previous shared memory and schedule erasure on exit |
63 | struct shm_remove |
64 | { |
65 | shm_remove() { shared_memory_object::remove(filename: "MySharedMemory" ); } |
66 | ~shm_remove(){ shared_memory_object::remove(filename: "MySharedMemory" ); } |
67 | } remover; |
68 | |
69 | //Create a shared memory object. |
70 | shared_memory_object shm(create_only,"MySharedMemory" ,read_write); |
71 | |
72 | try |
73 | { |
74 | // //Set size |
75 | // shm.truncate(sizeof(queue)); |
76 | // |
77 | // //Map the whole shared memory in this process |
78 | // mapped_region region(shm,read_write); |
79 | // |
80 | // //Get the address of the mapped region |
81 | // void *addr = region.get_address(); |
82 | |
83 | //Construct the shared structure in memory |
84 | queue *q = new (addr) queue; |
85 | |
86 | do |
87 | { |
88 | q->print(); |
89 | } while ( true ); |
90 | } |
91 | // catch(interprocess_exception &ex) |
92 | // { |
93 | // std::cout << ex.what() << std::endl; |
94 | // } |
95 | catch(boost::thread_interrupted&) |
96 | { |
97 | std::cout << "interrupted" << std::endl; |
98 | } |
99 | catch(...) |
100 | { |
101 | std::cout << "exception" << std::endl; |
102 | } |
103 | } |
104 | |
105 | int main() |
106 | { |
107 | addr = new queue(); |
108 | boost::thread t(printThread); |
109 | |
110 | // give the thread time to create the shm |
111 | boost::this_thread::sleep( rel_time: boost::posix_time::milliseconds( 1000 ) ); |
112 | |
113 | // //Create a shared memory object. |
114 | // shared_memory_object shm(open_only,"MySharedMemory",read_write); |
115 | |
116 | try |
117 | { |
118 | // //Map the whole shared memory in this process |
119 | // mapped_region region(shm,read_write); |
120 | // |
121 | // //Get the address of the mapped region |
122 | // void *addr = region.get_address(); |
123 | |
124 | //Obtain a pointer to the shared structure |
125 | queue *q = static_cast<queue*>(addr); |
126 | |
127 | item i; |
128 | i.i = 42; |
129 | q->put( item: i ); |
130 | |
131 | ++i.i; |
132 | q->put( item: i ); |
133 | |
134 | // give the printThread time to "process" the item |
135 | boost::this_thread::sleep( rel_time: boost::posix_time::milliseconds( 1000 ) ); |
136 | |
137 | t.interrupt(); |
138 | t.join(); |
139 | } |
140 | catch(...) |
141 | { |
142 | std::cout << "exception" << std::endl; |
143 | return -1; |
144 | } |
145 | } |
146 | |