在进程间通信时,对于消息的通信,有时候回用到信号量,本次就实现一个case,简单介绍信号量如何在进程之间实现消息收发的同步。
首先,了解一下信号量的定义,及接口类
class interprocess_semaphore
{
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
interprocess_semaphore(const interprocess_semaphore &);
interprocess_semaphore &operator=(const interprocess_semaphore &);
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a interprocess_semaphore with the given initial count.
//!interprocess_exception if there is an error.*/
interprocess_semaphore(unsigned int initialCount);
//!Destroys the interprocess_semaphore.
//!Does not throw
~interprocess_semaphore();
//!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
//!for the interprocess_semaphore, then one of these processes will return successfully from
//!its wait function. If there is an error an interprocess_exception exception is thrown.
void post();
//!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
//!then the calling process/thread blocks until it can decrement the counter.
//!If there is an error an interprocess_exception exception is thrown.
void wait();
//!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
//!and returns true. If the value is not greater than zero returns false.
//!If there is an error an interprocess_exception exception is thrown.
bool try_wait();
//!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
//!than zero and returns true. Otherwise, waits for the interprocess_semaphore
//!to the posted or the timeout expires. If the timeout expires, the
//!function returns false. If the interprocess_semaphore is posted the function
//!returns true. If there is an error throws sem_exception
bool timed_wait(const boost::posix_time::ptime &abs_time);
//!Returns the interprocess_semaphore count
// int get_count() const;
};
其次,构造一个消息的结构体
struct My_shared_memory_buffer
{
My_shared_memory_buffer() :mutex(0), empty(0), store(0)
{}
boost::interprocess::interprocess_semaphore mutex;
boost::interprocess::interprocess_semaphore empty;
boost::interprocess::interprocess_semaphore store;
int ItemData;
};
3. 创建一个进程A,这里只写了函数的形式,具体接口自己实现
void SharedMemory_Semaphore_A()
{
//remove shared memory on construction and destruction
struct shm_remove
{
shm_remove()
{
shared_memory_object::remove("MySharedMemory");
}
~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
}remover;
(void)remover;
shared_memory_object shm(create_only, "MySharedMemory", read_write);
shm.truncate(sizeof(My_shared_memory_buffer));
boost::interprocess::mapped_region region(shm, read_write);
void *addr = region.get_address();
My_shared_memory_buffer *data = new(addr)My_shared_memory_buffer;
const int Number = 10;
for (int i = 0; i < Number; i++)
{
data->empty.wait();
data->mutex.wait();
data->ItemData = i;
std::cout << " Set the Data:" << i << std::endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
data->mutex.post();
data->store.post();
}
}
4. 创建进程B
void SharedMemory_Semaphore_B()
{
//remove shared memory on construction and destruction
struct shm_remove
{
~shm_remove()
{
shared_memory_object::remove("MySharedMemory");
}
}remover;
(void)remover;
shared_memory_object shm(open_only, "MySharedMemory", read_write);
boost::interprocess::mapped_region region(shm, read_write);
void *addr = region.get_address();
My_shared_memory_buffer *data = static_cast<My_shared_memory_buffer*>(addr);
const int Number = 10;
int get_data;
(void)get_data;
while(true)
{
std::cout << "Store wait" << std::endl;
data->store.wait();
std::cout << "mutex wait" << std::endl;
data->mutex.wait();
get_data = data->ItemData;
std::cout << " get the Data:" << get_data << std::endl;
data->mutex.post();
data->empty.post();
}
}
5. 启动测试
注意: 用的时候,一定注意不要死锁,信号量的处理一定要小心。