更新我的另一个答案解决了线程之间的资源调度问题(在问题得到澄清之后)。
它显示了一种信号量方法来协调(许多)工作人员之间的工作,以及一种thread_pool
首先限制工作人员并将工作排队的方法。
在 linux(也许还有其他操作系统?)上,您可以使用锁定文件习语(但某些文件系统和旧内核不支持它)。
我建议使用进程间同步对象。
例如,使用名为 semaphore 的 Boost Interprocess:
#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread.hpp>
#include <cassert>
int main()
{
using namespace boost::interprocess;
named_semaphore sem(open_or_create, "ffed38bd-f0fc-4f79-8838-5301c328268c", 0ul);
if (sem.try_wait())
{
std::cout << "Oops, second instance\n";
}
else
{
sem.post();
// feign hard work for 30s
boost::this_thread::sleep_for(boost::chrono::seconds(30));
if (sem.try_wait())
{
sem.remove("ffed38bd-f0fc-4f79-8838-5301c328268c");
}
}
}
如果您在后台启动一个副本,新副本将在大约 30 秒内“拒绝”启动(“糟糕,第二个实例”)。
我觉得在这里颠倒逻辑可能更容易。嗯。让我试试。
一段时间过去了
呵呵。这比我想象的要棘手。
问题是,您要确保当您的应用程序被中断或终止时锁不会保留。为了分享便携式处理信号的技术:
#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread.hpp>
#include <cassert>
#include <boost/asio.hpp>
#define MAX_PROCESS_INSTANCES 3
boost::interprocess::named_semaphore sem(
boost::interprocess::open_or_create,
"4de7ddfe-2bd5-428f-b74d-080970f980be",
MAX_PROCESS_INSTANCES);
// to handle signals:
boost::asio::io_service service;
boost::asio::signal_set sig(service);
int main()
{
if (sem.try_wait())
{
sig.add(SIGINT);
sig.add(SIGTERM);
sig.add(SIGABRT);
sig.async_wait([](boost::system::error_code,int sig){
std::cerr << "Exiting with signal " << sig << "...\n";
sem.post();
});
boost::thread sig_listener([&] { service.run(); });
boost::this_thread::sleep_for(boost::chrono::seconds(3));
service.post([&] { sig.cancel(); });
sig_listener.join();
}
else
{
std::cout << "More than " << MAX_PROCESS_INSTANCES << " instances not allowed\n";
}
}
那里有很多可以解释的。如果您有兴趣,请告诉我。
注意很明显,如果kill -9
在您的应用程序中使用(强制终止),那么所有的赌注都将被取消,您必须删除 Name Semaphore 对象或显式解锁它(post()
)。
这是我系统上的测试:
sehe@desktop:/tmp$ (for a in {1..6}; do ./test& done; time wait)
More than 3 instances not allowed
More than 3 instances not allowed
More than 3 instances not allowed
Exiting with signal 0...
Exiting with signal 0...
Exiting with signal 0...
real 0m3.005s
user 0m0.013s
sys 0m0.012s