2017-09-18 29 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标志。