Implementing a simple, generic thread pool in C++11

前端 未结 2 523
后悔当初
后悔当初 2021-02-04 19:16

I want to create a thread pool for experimental purposes (and for the fun factor). It should be able to process a wide variety of tasks (so I can possibly use it in later projec

2条回答
  •  感情败类
    2021-02-04 19:53

    So the hard part is that packaged_task is move-only, otherwise you could just toss it into a std::function, and run those in your threads.

    There are a few ways around this.

    First, ridiculously, use a packaged_task to store a packaged_task. I'd advise against this, but it does work. ;) (what is the signature of operator() on packaged_task? What is the required signature for the objects you pass to packaged_task?)

    Second, wrap your packaged_task in a shared_ptr, capture that in a lambda with signature void(), store that in a std::function, and done. This has overhead costs, but probably less than the first solution.

    Finally, write your own move-only function wrapper. For the signature void() it is short:

    struct task {
      template,
        class=decltype( std::declval()() )
      >
      task( F&& f ):
        ptr(
          new dF(std::forward(f)),
          [](void* ptr){ delete static_cast(ptr); }
        ),
        invoke([](void*ptr){
          (*static_cast(ptr))();
        })
      {}
      void operator()()const{
        invoke( ptr.get() );
      }
      task(task&&)=default;
      task&operator=(task&&)=default;
      task()=default;
      ~task()=default;
      explicit operator bool()const{return static_cast(ptr);}
    private:
      std::unique_ptr ptr;
      void(*invoke)(void*) = nullptr;
    };
    

    and simple. The above can store packaged_task for any type R, and invoke them later.

    This has relatively minimal overhead -- it should be cheaper than std::function, at least the implementations I've seen -- except it does not do SBO (small buffer optimization) where it stores small function objects internally instead of on the heap.

    You can improve the unique_ptr<> ptr container with a small buffer optimization if you want.

提交回复
热议问题