【问题标题】:Thread pool queue is not getting updated with pushed items, though push is successful尽管推送成功,但线程池队列没有更新推送的项目
【发布时间】:2016-05-26 13:18:54
【问题描述】:

我有一个简单的线程池实现。实现如下-

问题是当我在队列中插入一个项目时,它不会反映在线程池函数 void worker_thread() 中,即检查 worker_thread() 函数中的 (work_queue.try_pop(task)) 是否总是失败并且任务是没有被线程拾起。 你能指出我做错了什么吗?

提前致谢。

template<typename T>
class threadsafe_queue
{
private:
    mutable std::mutex mut;
    std::queue<T> data_queue;
    std::condition_variable data_cond;
public:
    threadsafe_queue()
    {}

    void push(T new_value)
    {
        std::lock_guard<std::mutex> lk(mut);
        data_queue.push(std::move(new_value));
        data_cond.notify_one();
    }

    void wait_and_pop(T& value)
    {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this]{return !data_queue.empty(); });
        value = std::move(data_queue.front());
        data_queue.pop();
    }

    std::shared_ptr<T> wait_and_pop()
    {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this]{return !data_queue.empty(); });
        std::shared_ptr<T> res(
            std::make_shared<T>(std::move(data_queue.front())));
        data_queue.pop();
        return res;
    }

    bool try_pop(T& value)
    {
        std::lock_guard<std::mutex> lk(mut);
        if (data_queue.empty())
            return false;
        value = std::move(data_queue.front());
        data_queue.pop();
    }

    std::shared_ptr<T> try_pop()
    {
        std::lock_guard<std::mutex> lk(mut);
        if (data_queue.empty())
            return std::shared_ptr<T>();
        std::shared_ptr<T> res(
            std::make_shared<T>(std::move(data_queue.front())));
        data_queue.pop();
        return res;
    }

    bool empty() const
    {
        std::lock_guard<std::mutex> lk(mut);
        return data_queue.empty();
    }
};

class thread_pool
{
    threadsafe_queue<std::function<void()>> work_queue;
    std::atomic<bool> done;
    int thread_count;
    std::vector<std::thread> threads;

    void worker_thread()
    {
        while (!done)
        {
            std::function<void()> task;
            if (work_queue.try_pop(task)) // here work_queue is always empty.
            {
                task();
            }
            else
            {
                std::this_thread::yield();
            }
        }
    }
public:
    thread_pool(unsigned thread_count = 5) : done(false), thread_count(thread_count)
    {
        try
        {
            for (unsigned i = 0; i < thread_count; ++i)
            {
                threads.emplace_back(std::thread(&thread_pool::worker_thread, this));
            }
        }
        catch (...)
        {
            done = true;
            throw;
        }
    }

    ~thread_pool()
    {
        done = true;
        for (unsigned i = 0; i < thread_count; ++i)
        {
            threads[i].join();
        }
    }
    template <typename FunctionType>
    void submit(FunctionType f)
    {
        work_queue.push(std::function<void()>(f)); // this shows proper size of queue after push.
    }
};

void fun()
 {
    cout << "hi"<<this_thread::get_id(); // this funciton is never being executed by thread pool.
}
template<class T>
class A
 {
  private:
     int x{ 3 };
public:
      void fun(vector<string> &v)  // this funciton is never being executed by thread pool.
      {
         std::cout << v[0].c_str() << endl;
          x = 5;
      }

};

     int main()
    {
        thread_pool tp(2);
         vector<string> v{ "1", "2" };
          A<int> a;
          tp.submit([&] { a.fun(std::ref(v)); });
         tp.submit < void()>(fun);
         std::this_thread::sleep_for(std::chrono::seconds(10));
         return 0;
    }

【问题讨论】:

  • 为什么你的工作线程旋转屈服,为什么他们不做wait_and_pop?其次,在您的队列上拥有abort() 功能很有用,它可以用来告诉线程队列即将到期。通常,当没有工作时,不应该做任何工作:即使没有工作要做,你的每个工作线程也会占用 1 个 CPU。

标签: c++ multithreading c++11


【解决方案1】:

您的try_pop() 方法中缺少return true; 语句。您应该在启用警告的情况下进行编译,编译器会指出:

ttt.cpp: 在成员函数'bool threadsafe_queue::try_pop(T&) [with T = std::function]’:ttt.cpp:57:5:警告:控制 到达非空函数的结尾[-Wreturn-type]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多