gpt4 book ai didi

c++ - C++如何限制运行实例数

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:20:10 24 4
gpt4 key购买 nike

我有一个分配大量内存的 C++ 类。它通过调用第三方库来实现这一点,该库旨在在无法分配内存时崩溃,有时我的应用程序会在并行线程中创建我的类的多个实例。线程太多,我崩溃了。我最好的解决方案是确保永远不会同时运行三个以上的实例。 (这是一个好主意吗?)我目前实现那个的最佳想法是使用 boost 互斥体。类似于以下伪代码,

MyClass::MyClass(){
my_thread_number = -1; //this is a class variable
while (my_thread_number == -1)
for (int i=0; i < MAX_PROCESSES; i++)
if(try_lock a mutex named i){
my_thread_number = i;
break;
}
//Now I know that my thread has mutex number i and it is allowed to run
}

MyClass::~MyClass(){
release mutex named my_thread_number
}

如您所见,我不太确定这里互斥锁的确切语法。所以总结一下,我的问题是

  1. 当我想通过限制线程数来解决我的内存错误时,我走在正确的轨道上吗?
  2. 如果是,我应该使用互斥锁还是其他方式来实现?
  3. 如果是,我的算法合理吗?
  4. 有没有关于如何将 try_lock 与 boost 互斥锁一起使用的很好的示例?

编辑:我意识到我在谈论线程,而不是进程。编辑:我参与构建了一个可以在 linux 和 Windows 上运行的应用程序......

最佳答案

UPDATE My other answer addresses scheduling resources among threads (after the question was clarified).

It shows both a semaphore approach to coordinate work among (many) workers, and a thread_pool to limit workers in the first place and queue the work.

在 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";
}
}

那里有很多可以解释的东西。如果您有兴趣,请告诉我。

NOTE It should be quite obvious that if kill -9 is used on your application (forced termination) then all bets are off and you'll have to either remove the Name Semaphore object or explicitly unlock it (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

关于c++ - C++如何限制运行实例数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22545789/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com