作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
摘要
我提供了一个小代码示例,该代码重现了我的软件中的一个非常奇怪的错误。它使用 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_Sleep1
或 FOOBAR_FOOBAR_Sleep1
而失败。它看起来很奇怪,我想我没有正确使用它并且我处于随机行为......
配置
编译行
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
注意:出于兼容性原因,我不使用 C++11。
最佳答案
Named semaphors in boost are implying Kernel or Filesystem persistence因此,当您通过 open_or_create
时,可能存在具有指定名称的现有命名信号量(可能来自之前中断的启动?),在这种情况下,sem_count
将被忽略并且信号量将在无论它处于何种状态。在创建或传递 create_only
标志之前尝试调用 named_semaphore::remove
。
关于c++ - 我的信号量(来自 Boost 的 named_semaphore)做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46276634/
我是一名优秀的程序员,十分优秀!