結構
- What's A Semaphore?
- Boost.Interprocess Semaphore Types And Headers
- Anonymous semaphore example
What's A Semaphore?
- 旗語是一種基于內部計數的進程間同步機制,它提供了兩種基本操作。
- 等待:測試旗語數的值,如果小于或等于0,則等待,否則遞減旗語數。
- Post:增加旗語數。增加信號量 如果有進程被阻塞,則喚醒其中一個進程。
- 如果初始旗語數被初始化為1,則Wait操作相當于mutex鎖定,Post相當于mutex解鎖。這種類型的semaphore被稱為二進制semaphore。
- 雖然旗語可以像mutexes一樣使用,但它們有一個獨特的特點:與mutexes不同,Post操作不需要由執行Wait操作的同一個線程/進程執行。
Boost.Interprocess Semaphore Types And Headers
- Boost.Interprocess offers the following semaphore types:
- #include <boost/interprocess/sync/interprocess_semaphore.hpp>
interprocess_semaphore
: An anonymous semaphore that can be placed in shared memory or memory mapped files.- interprocess_semaphore。一個匿名的信號體,可以放在共享內存或內存映射文件中。
- #include <boost/interprocess/sync/named_semaphore.hpp>
named_semaphore
: A named semaphore.- named_semaphore。一個命名的旗語。
Anonymous semaphore example
- We will implement an integer array in shared memory that will be used to transfer data from one process to another process. The first process will write some integers to the array and the process will block if the array is full.
- The second process will copy the transmitted data to its own buffer, blocking if there is no new data in the buffer.
- This is the shared integer array (doc_anonymous_semaphore_shared_data.hpp):
- 我們將在共享內存中實現一個整數數組,用于從一個進程向另一個進程傳輸數據。第一個進程將向數組寫入一些整數,如果數組已滿,該進程將阻塞。
- 第二個進程將把傳輸的數據復制到自己的緩沖區,如果緩沖區中沒有新的數據,則阻塞。
- 這就是共享整數數組(doc_anonymous_semaphore_shared_data.hpp)。
#include <boost/interprocess/sync/interprocess_semaphore.hpp>struct shared_memory_buffer
{enum { NumItems = 10 };shared_memory_buffer(): mutex(1), nempty(NumItems), nstored(0){}//Semaphores to protect and synchronize accessboost::interprocess::interprocess_semaphoremutex, nempty, nstored;//Items to fillint items[NumItems];
};
- 這是進程主進程。創建共享內存,將整數數組放置在那里,并逐個開始整數,如果數組滿了,則阻塞。
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
#include "doc_anonymous_semaphore_shared_data.hpp"using namespace boost::interprocess;int main ()
{//Remove shared memory on construction and destructionstruct shm_remove{shm_remove() { shared_memory_object::remove("MySharedMemory"); }~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }} remover;//Create a shared memory object.shared_memory_object shm(create_only //only create,"MySharedMemory" //name,read_write //read-write mode);//Set sizeshm.truncate(sizeof(shared_memory_buffer));//Map the whole shared memory in this processmapped_region region(shm //What to map,read_write //Map it as read-write);//Get the address of the mapped regionvoid * addr = region.get_address();//Construct the shared structure in memoryshared_memory_buffer * data = new (addr) shared_memory_buffer;const int NumMsg = 100;//Insert data in the arrayfor(int i = 0; i < NumMsg; ++i){data->nempty.wait();data->mutex.wait();data->items[i % shared_memory_buffer::NumItems] = i;data->mutex.post();data->nstored.post();}return 0;
}
The second process opens the shared memory and copies the received integers to it's own buffer:
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
#include "doc_anonymous_semaphore_shared_data.hpp"using namespace boost::interprocess;int main ()
{//Remove shared memory on destructionstruct shm_remove{~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }} remover;//Create a shared memory object.shared_memory_object shm(open_only //only create,"MySharedMemory" //name,read_write //read-write mode);//Map the whole shared memory in this processmapped_region region(shm //What to map,read_write //Map it as read-write);//Get the address of the mapped regionvoid * addr = region.get_address();//Obtain the shared structureshared_memory_buffer * data = static_cast<shared_memory_buffer*>(addr);const int NumMsg = 100;int extracted_data [NumMsg];//Extract the datafor(int i = 0; i < NumMsg; ++i){data->nstored.wait();data->mutex.wait();extracted_data[i] = data->items[i % shared_memory_buffer::NumItems];data->mutex.post();data->nempty.post();}return 0;
}
- The same interprocess communication can be achieved with a condition variables and mutexes, but for several synchronization patterns, a semaphore is more efficient than a mutex/condition combination.
- 同樣的進程間通信可以用條件變量和mutexes來實現,但對于幾種同步模式,semaphore比mutex/條件組合更有效率。