2017-09-18 30 views
3

摘要我在做什麼我的信號量錯誤(來自Boost的named_semaphore)?

我目前的代碼再生一個很奇怪的錯誤我有我的軟件一個小例子。它使用Boost創建3個名爲信號量,並在單個線程中等待每個信號量。這工作。但是如果我改變信號量的名稱(通過添加一個給定的前綴),它不會:第3個信號量無故等待無限的時間。

詳細信息(源代碼和行爲)

#include <string> 
#include <vector> 
#include <iostream> 
#include <boost/thread.hpp> 
#include <boost/date_time.hpp> 
#include <boost/interprocess/sync/named_semaphore.hpp> 

struct Lock 
{ 
    std::string name; 
    unsigned int count; 
    Lock(const std::string& name_, unsigned int count_) : name(name_), count(count_) {} 
}; 

int main() 
{ 
    std::vector<Lock> locks; 
    locks.push_back(Lock("Sleep1", 1)); 
    locks.push_back(Lock("Hello", 1)); 
    locks.push_back(Lock("Sleep2", 1)); 

    for(std::size_t i = 0; i < locks.size(); ++i) 
    { 
     { 
      const std::string sem_name = locks[i].name; 
      const unsigned int sem_count = locks[i].count; 
      std::cout << "Open or Create semaphore (" << sem_name << ", " << sem_count << ")" << std::endl; 
      boost::interprocess::named_semaphore semaphore(boost::interprocess::open_or_create, sem_name.c_str(), sem_count); 
      std::cout << "Wait..." << std::flush; 
      semaphore.wait(); 
      std::cout << " DONE" << std::endl; 
     } 
     boost::this_thread::sleep(boost::posix_time::seconds(5)); 
     { 
      const std::string sem_name = locks[i].name; 
      std::cout << "Open semaphore (" << sem_name << ")" << std::endl; 
      boost::interprocess::named_semaphore semaphore(boost::interprocess::open_only, sem_name.c_str()); 
      std::cout << "Post..." << std::flush; 
      semaphore.post(); 
      std::cout << " DONE" << std::endl; 
     } 
    } 

    return 0; 
} 

執行這個例子中,我得到以下(預期)輸出:

> ./sem 
Open or Create semaphore (Sleep1, 1) 
Wait... DONE 
Open semaphore (Sleep1) 
Post... DONE 
Open or Create semaphore (Hello, 1) 
Wait... DONE 
Open semaphore (Hello) 
Post... DONE 
Open or Create semaphore (Sleep2, 1) 
Wait... DONE 
Open semaphore (Sleep2) 
Post... DONE 

如果我更換定義的名稱行信號量如下:

std::vector<Lock> locks; 
locks.push_back(Lock("CHAIN_EVALUATOR_Sleep1", 1)); 
locks.push_back(Lock("CHAIN_EVALUATOR_Hello", 1)); 
locks.push_back(Lock("CHAIN_EVALUATOR_Sleep2", 1)); 

執行不會以下列輸出結束:

Open or Create semaphore (CHAIN_EVALUATOR_Sleep1, 1) 
Wait... DONE 
Open semaphore (CHAIN_EVALUATOR_Sleep1) 
Post... DONE 
Open or Create semaphore (CHAIN_EVALUATOR_Hello, 1) 
Wait... DONE 
Open semaphore (CHAIN_EVALUATOR_Hello) 
Post... DONE 
Open or Create semaphore (CHAIN_EVALUATOR_Sleep2, 1) 
Wait... 

請注意新名稱的奇怪選擇。事實上,它失敗了。它不會因FOO_BAR_FOO_BAR_Sleep1FOOBAR_FOOBAR_Sleep1而失敗。它看起來太奇怪了,我想我沒有正確地使用它,我在一個隨機行爲......

配置

  • 的Linux的openSUSE 42.1
  • GCC 4.8.5
  • 升壓1.64.0(包括的Boost.Python 與Python 2.7.9)

編譯線

g++ test_semaphore.cpp -o sem \ 
-I /softs/boost/1.64.0/python/2.7.9/64/gcc/4.8.5/include \ 
/softs/boost/1.64.0/python/2.7.9/64/gcc/4.8.5/lib/libboost_date_time-mt.a \ 
/softs/boost/1.64.0/python/2.7.9/64/gcc/4.8.5/lib/libboost_thread-mt.a \ 
/softs/boost/1.64.0/python/2.7.9/64/gcc/4.8.5/lib/libboost_system-mt.a \ 
-l pthread 

注:我不使用下的兼容性原因++ 11。

+2

嘗試在創建之前調用'named_semaphore :: remove'。既然你傳遞了'open_or_create',那麼可能會存在指定名稱的現有命名信號量(從以前的中斷啓動可能?)。 – VTT

+0

@VTT確實,這是錯誤的原因。我可以在適當的時候通過殺死我的可執行文件來生成我想要的名稱。請添加一個答案,我會接受它。現在我的問題是控制第一次調用之前刪除。 – Caduchon

回答

2

Named semaphors in boost are implying Kernel or Filesystem persistence所以當你通過open_or_create有可能在現有信號燈具有指定名稱命名的(從以前中斷的推出也許?),在這種情況下sem_count將被忽略,信號會以什麼狀態時,它一直留在試着在創建之前調用named_semaphore::remove或通過create_only標誌。