简体   繁体   English

C ++中的线程池设计

[英]thread pool design in C++

I am not sure how to put this question in this forum any way i am asking and hopefully get some inputs. 我不确定如何以任何方式在这个论坛中提出这个问题,并希望能得到一些投入。

I am writing a thread pool for my project. 我正在为我的项目编写线程池。 I have following design. 我有以下设计。

  1. I am maintaining vector of threads std::vector<ThreadWrapper <threadFuncParam>* > m_vecThreads; 我正在维护线程std::vector<ThreadWrapper <threadFuncParam>* > m_vecThreads;

  2. and pushing the threds in to list m_vecThreads.push_back(pThreadWrapper); 并将其推入列表m_vecThreads.push_back(pThreadWrapper);

  3. When new request comes i am taking the thread pool as below 当新请求到来时,我正在如下线程池中

     if(!m_vecThreads.empty() ) { ThreadWrapper <threadFuncParam>* pWrapper = m_vecThreads.back(); m_vecThreads.pop_back(); //... Awake threadd } 
  4. When thread job is done it is pushed back in to pool of thread. 线程作业完成后,将其推回到线程池中。

Now while gracefull shutdown i have stop the threads gracefully now with the design above i am facing problem how can i stop threads as in vector container i am poping from vector when request is serviced, so i lost the pointer till service is completed. 现在,当gracefull关闭时,我已经使用上面的设计从现在开始优雅地停止线程了。我面临的问题是,如何在请求容器中停止从向量容器中弹出的线程,而在向量中弹出请求,因此我丢失了指针,直到服务完成为止。 Is there better i can do this or handle this scenario like map or other container which is supported by standard C++? 我能做些更好的事情还是可以处理这种情况,例如地图或标准C ++支持的其他容器?

Another question is 另一个问题是

During shutdown i have a scenario threads are doing process here in my case reading from database which may take time so i cannot wait till it is complete and i want to send reply to clients for pending requests which threads are processing and i am about to kill that value is bad. 在关机期间,在我的情况下,我有一个场景线程正在处理数据库,这可能需要花费一些时间,因此我无法等待它完成,并且我想向正在处理线程的未决请求发送答复给客户端,并且我将要杀死这个值是不好的。

Thanks! 谢谢!

If you still need access to what you pass out from your pool, then you should store the items in a "used" container. 如果您仍需要访问从池中传出的内容,则应将这些项目存储在“使用过的”容器中。
However, at that moment, you are sharing your pointers, so you should use shared_ptr and pass out weak_ptr, so the threads can also be deleted and the users don't have a dangling pointer 但是,此时,您正在共享指针,因此您应该使用shared_ptr并传递weak_ptr,以便也可以删除线程,并且用户没有悬空的指针。

The best cointainer for the used items would be a set, so the returned thread can be found and removed easily. 最适合使用过的物品的硬币容器是一套,因此可以轻松找到并删除返回的线程。

To solve your first problem, push it on to another vector, say m_vecBusyThreads , and when it's done, take it off there (note, you'll have to have some mechanism to search for the finished thread). 要解决您的第一个问题,请将其推入另一个向量,例如m_vecBusyThreads ,完成后,将其取下(请注意,您必须具有某种机制来搜索完成的线程)。

For your second problem, cleanest solution is to join each thread till it has "shutdown", any other approach could end up with some undesired side effects (esp. for example if it's connecting to a db etc.) Now that you have the busy container, iterate through tell each to shutdown, then iterate through each of your free containers, shutting down and joining each thread. 对于第二个问题,最干净的解决方案是加入每个线程,直到它“关闭”为止,任何其他方法都可能导致一些不良后果(例如,例如,如果它正在连接到db等)。容器,遍历每个容器,然后遍历每个空闲容器,关闭并加入每个线程。 Then go back to the busy container and attempt to join each thread. 然后返回到繁忙的容器并尝试加入每个线程。 This may give a little time to the busy threads to shutdown cleanly. 这可能会给繁忙的线程腾出一些时间来彻底关闭它们。

boost::threads supports this concept of interrupt points, and the idea is that you can interrupt a thread at any of these points, however some calls are not interruptible (typically blocking calls), you need to find the best way to stop each type (socket read for example may be to send a dummy packet etc.) boost :: threads支持这种中断点的概念,其思想是您可以在任何这些点处中断线程,但是某些调用是不可中断的(通常是阻塞调用),您需要找到停止每种类型的最佳方法(例如,读取的套接字可能是发送虚拟数据包等)

I have done it in C, so the solution is not "C++"ish, but I was using two arrays: one containing the threads, and the other containing a representation of used / unused (~boolean). 我已经用C完成了,所以解决方案不是“ C ++”式的,但是我使用的是两个数组:一个包含线程,另一个包含使用/未使用(〜布尔值)的表示。

I would be something like: 我会是这样的:

pthread_t[INITIAL_SIZE] thread_pool;
boolean[INITIAL_SIZE] threads_availability;
int first_available = 0;

pthread_t * get_thread() {
   int ind = 0;
   if (first_available<=INITIAL_SIZE) {
      ind = first_available;
      // find the next available spot
      for (first_available; first_available < INITIAL_SIZE && threads_availability[first_available]; first_available++);
      threads_availability[ind] = 0;

      return thread_pool[ind];
   }
}

void put_thread(pthread_t* thethread)
{
    int i = 0;
    pthread_t *it = thread_pool;
    while (!pthread_equals(it, thethread)) {
        it++;
        i++;
    }
    thread_availability[i] = 1;
}

please keep in mind that this is pseudo code, and this is not optimal. 请记住,这是伪代码,这不是最佳选择。 But this is an idea. 但这是一个主意。

This is not a direct answer to your problem as other people already answered your original question. 这不是您的问题的直接答案,因为其他人已经回答了您的原始问题。

I just wanted to say that you could look into boost::asio and/or boost::thread. 我只是想说您可以研究boost :: asio和/或boost :: thread。 I would probably go for boost::asio because it has everything you need to do asynchronous operations based on timers and whatnot. 我可能会去使用boost :: asio,因为它具有您需要进行所有基于计时器等的异步操作所需的一切。 You could use shared_ptr and boost::enable_shared_from_this in order to let your "jobs" go and be destroyed automatically when they finish their job. 您可以使用shared_ptr和boost :: enable_shared_from_this来使您的“工作”完成工作后自动销毁。

Example: 例:

boost::shared_ptr<async_job> aj( new async_job(
   io_, boost::bind(&my_job::handle_completion, shared_from_this(), _1, _2)));

This code would execute your custom async_job on a thread pool (io_ is boost::asio::io_service). 此代码将在线程池上执行您的自定义async_job(io_是boost :: asio :: io_service)。 Your 'my_job' instance will be automatically destroyed when the async_job finishes and invokes handle_completion on it. 当async_job完成并在其上调用handle_completion时,您的“ my_job”实例将被自动销毁。 Or you can let it live if you take shared_from_this() again inside handle_completion. 或者,如果再次在handle_completion中使用shared_from_this(),则可以启用它。

HTH, Alex 亚历克斯(HTH)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM