Abstract
I present a small example of code reproducing a very strange bug I have in my software. It creates 3 named semaphores with Boost, and waits for each in a single thread. This works. But if I change the names of the semaphores (by adding a given prefix), it doesn't: the 3th semaphore waits for infinite time with no reason.
Details (source code and behavior)
#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;
}
Executing this example, I get the following (expected) output:
> ./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
If I replace the line defining the names of the semaphores by the following:
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));
the execution doesn't terminate with the following output:
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...
Note the strange choice for the new names. Actually, it fails with that. It doesn't fail with FOO_BAR_FOO_BAR_Sleep1
, nor FOOBAR_FOOBAR_Sleep1
. It looks so strange, I suppose I don't use it correctly and I'm in a random behavior...
Configuration
- Linux openSUSE 42.1
- GCC 4.8.5
- Boost 1.64.0 (including Boost.Python with python 2.7.9)
Compilation line
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
Note : I don't use C++11 for compatibility reason.