<tfoot id='12CXh'></tfoot>

        <legend id='12CXh'><style id='12CXh'><dir id='12CXh'><q id='12CXh'></q></dir></style></legend>
        <i id='12CXh'><tr id='12CXh'><dt id='12CXh'><q id='12CXh'><span id='12CXh'><b id='12CXh'><form id='12CXh'><ins id='12CXh'></ins><ul id='12CXh'></ul><sub id='12CXh'></sub></form><legend id='12CXh'></legend><bdo id='12CXh'><pre id='12CXh'><center id='12CXh'></center></pre></bdo></b><th id='12CXh'></th></span></q></dt></tr></i><div id='12CXh'><tfoot id='12CXh'></tfoot><dl id='12CXh'><fieldset id='12CXh'></fieldset></dl></div>

      1. <small id='12CXh'></small><noframes id='12CXh'>

        • <bdo id='12CXh'></bdo><ul id='12CXh'></ul>

        C++中如何限制运行实例的数量

        时间:2023-07-20

            <tfoot id='RNlao'></tfoot>

              • <bdo id='RNlao'></bdo><ul id='RNlao'></ul>
                1. <i id='RNlao'><tr id='RNlao'><dt id='RNlao'><q id='RNlao'><span id='RNlao'><b id='RNlao'><form id='RNlao'><ins id='RNlao'></ins><ul id='RNlao'></ul><sub id='RNlao'></sub></form><legend id='RNlao'></legend><bdo id='RNlao'><pre id='RNlao'><center id='RNlao'></center></pre></bdo></b><th id='RNlao'></th></span></q></dt></tr></i><div id='RNlao'><tfoot id='RNlao'></tfoot><dl id='RNlao'><fieldset id='RNlao'></fieldset></dl></div>

                  <small id='RNlao'></small><noframes id='RNlao'>

                    <tbody id='RNlao'></tbody>

                  <legend id='RNlao'><style id='RNlao'><dir id='RNlao'><q id='RNlao'></q></dir></style></legend>

                2. 本文介绍了C++中如何限制运行实例的数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

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

                  I have a c++ class that allocates a lot of memory. It does this by calling a third-party library that is designed to crash if it cannot allocate the memory, and sometimes my application creates several instances of my class in parallel threads. With too many threads I have a crash. My best idea for a solution is to make sure that there are never, say, more than three instances running at the same time. (Is this a good idea?) And my current best idea for implementing that is to use a boost mutex. Something along the lines of the following pseudo-code,

                  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
                  }
                  

                  如您所见,我不太确定此处互斥锁的确切语法.总而言之,我的问题是

                  As you see, I am not quite sure of the exact syntax for mutexes here.. So summing up, my questions are

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

                  <小时>

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


                  I realized I am talking about threads, not processes. I am involved in building an application that can run on both linux and Windows...

                  推荐答案

                  这是实现您自己的信号量"的一种简单方法(因为我认为标准库或 boost 没有).这选择了一种合作"的方法,工人会互相等待:

                  Here's a simplistic way to implement your own 'semaphore' (since I don't think the standard library or boost have one). This chooses a 'cooperative' approach and workers will wait for each other:

                  #include <boost/thread.hpp>
                  #include <boost/phoenix.hpp>
                  
                  using namespace boost;
                  using namespace boost::phoenix::arg_names;
                  
                  void the_work(int id)
                  {
                      static int running = 0;
                      std::cout << "worker " << id << " entered (" << running << " running)
                  ";
                  
                      static mutex mx;
                      static condition_variable cv;
                  
                      // synchronize here, waiting until we can begin work
                      {
                          unique_lock<mutex> lk(mx);
                          cv.wait(lk, phoenix::cref(running) < 3);
                          running += 1;
                      }
                  
                      std::cout << "worker " << id << " start work
                  ";
                      this_thread::sleep_for(chrono::seconds(2));
                      std::cout << "worker " << id << " done
                  ";
                  
                      // signal one other worker, if waiting
                      {
                          lock_guard<mutex> lk(mx);
                          running -= 1;
                          cv.notify_one(); 
                      }
                  }
                  
                  int main()
                  {
                      thread_group pool;
                  
                      for (int i = 0; i < 10; ++i)
                          pool.create_thread(bind(the_work, i));
                  
                      pool.join_all();
                  }
                  

                  现在,我认为最好有一个由 n 个工人组成的专用池轮流从队列中取出他们的工作:

                  Now, I'd say it's probably better to have a dedicated pool of n workers taking their work from a queue in turns:

                  #include <boost/thread.hpp>
                  #include <boost/phoenix.hpp>
                  #include <boost/optional.hpp>
                  
                  using namespace boost;
                  using namespace boost::phoenix::arg_names;
                  
                  class thread_pool
                  {
                    private:
                        mutex mx;
                        condition_variable cv;
                  
                        typedef function<void()> job_t;
                        std::deque<job_t> _queue;
                  
                        thread_group pool;
                  
                        boost::atomic_bool shutdown;
                        static void worker_thread(thread_pool& q)
                        {
                            while (auto job = q.dequeue())
                                (*job)();
                        }
                  
                    public:
                        thread_pool() : shutdown(false) {
                            for (unsigned i = 0; i < boost::thread::hardware_concurrency(); ++i)
                                pool.create_thread(bind(worker_thread, ref(*this)));
                        }
                  
                        void enqueue(job_t job) 
                        {
                            lock_guard<mutex> lk(mx);
                            _queue.push_back(std::move(job));
                  
                            cv.notify_one();
                        }
                  
                        optional<job_t> dequeue() 
                        {
                            unique_lock<mutex> lk(mx);
                            namespace phx = boost::phoenix;
                  
                            cv.wait(lk, phx::ref(shutdown) || !phx::empty(phx::ref(_queue)));
                  
                            if (_queue.empty())
                                return none;
                  
                            auto job = std::move(_queue.front());
                            _queue.pop_front();
                  
                            return std::move(job);
                        }
                  
                        ~thread_pool()
                        {
                            shutdown = true;
                            {
                                lock_guard<mutex> lk(mx);
                                cv.notify_all();
                            }
                  
                            pool.join_all();
                        }
                  };
                  
                  void the_work(int id)
                  {
                      std::cout << "worker " << id << " entered
                  ";
                  
                      // no more synchronization; the pool size determines max concurrency
                      std::cout << "worker " << id << " start work
                  ";
                      this_thread::sleep_for(chrono::seconds(2));
                      std::cout << "worker " << id << " done
                  ";
                  }
                  
                  int main()
                  {
                      thread_pool pool; // uses 1 thread per core
                  
                      for (int i = 0; i < 10; ++i)
                          pool.enqueue(bind(the_work, i));
                  }
                  

                  附注.如果您愿意,您可以在那里使用 C++11 lambdas 而不是 boost::phoenix.

                  PS. You can use C++11 lambdas instead boost::phoenix there if you prefer.

                  这篇关于C++中如何限制运行实例的数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:将 boost::asio::async_read 与 stdin 一起使用? 下一篇:没有了

                  相关文章

                  <i id='4Xf7H'><tr id='4Xf7H'><dt id='4Xf7H'><q id='4Xf7H'><span id='4Xf7H'><b id='4Xf7H'><form id='4Xf7H'><ins id='4Xf7H'></ins><ul id='4Xf7H'></ul><sub id='4Xf7H'></sub></form><legend id='4Xf7H'></legend><bdo id='4Xf7H'><pre id='4Xf7H'><center id='4Xf7H'></center></pre></bdo></b><th id='4Xf7H'></th></span></q></dt></tr></i><div id='4Xf7H'><tfoot id='4Xf7H'></tfoot><dl id='4Xf7H'><fieldset id='4Xf7H'></fieldset></dl></div>
                3. <tfoot id='4Xf7H'></tfoot>

                  1. <small id='4Xf7H'></small><noframes id='4Xf7H'>

                    <legend id='4Xf7H'><style id='4Xf7H'><dir id='4Xf7H'><q id='4Xf7H'></q></dir></style></legend>
                        <bdo id='4Xf7H'></bdo><ul id='4Xf7H'></ul>