线程池的调用顺序

线程池中的线程执行顺序与提交任务的方式有关。线程池中的线程执行任务时,有两种方式:先进先出(`FIFO`)和优先级队列(`Priority`)。线程执行任务的过程如下:

1. 当有新任务添加到线程池中时,如果当前线程数小于核心线程数,则会创建新的线程并立即执行该任务。

2. 如果当前线程数等于核心线程数,新任务被加入到工作队列中,排在先前添加的任务之后。如果队列已满,则创建新的线程来执行该任务。

3. 工作队列中的任务是按照先进先出的顺序执行的。当队列中没有任务时,线程会阻塞,直到新任务加入为止。

4. 如果线程池中的线程数超过了核心线程数,那么当线程处于空闲状态时,它将等待一段时间(keepAliveTime),如果在这段时间内没有新任务需要执行,那么该线程就会被终止,以便回收资源。

5. 线程池的优先级队列,与普通队列的区别在于可以设置任务的优先级。当线程池中有多个任务时,会按照优先级执行。任务的优先级由用户自定义,可以通过实现`Comparable`或`Comparator`接口并覆写`compareTo`或`compare`方法来实现。优先级队列中的任务是按照优先级从高到低依次执行的。

综上所述,线程池中的线程调用顺序取决于任务提交的方式和是否使用优先级队列。一般来说,线程池中的任务执行顺序是先进先出的。如果使用优先级队列,则会按照优先级从高到低的顺序执行任务。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要利用线程池调用其他函数,需要将需要执行的函数封装成一个任务(Task),并将任务提交给线程池。下面是一个简单的例子: ```c++ #include <iostream> #include <thread> #include <vector> #include <queue> #include <functional> #include <mutex> #include <condition_variable> class ThreadPool { public: using Task = std::function<void()>; explicit ThreadPool(std::size_t numThreads) { start(numThreads); } ~ThreadPool() { stop(); } template<class T> auto enqueue(T task) -> std::future<decltype(task())> { auto wrapper = std::make_shared<std::packaged_task<decltype(task()) ()>>(std::move(task)); { std::unique_lock<std::mutex> lock{mEventMutex}; mTasks.emplace([=] { (*wrapper)(); }); } mEventVar.notify_one(); return wrapper->get_future(); } private: std::vector<std::thread> mThreads; std::condition_variable mEventVar; std::mutex mEventMutex; bool mStopping = false; std::queue<Task> mTasks; void start(std::size_t numThreads) { for (auto i = 0u; i < numThreads; ++i) { mThreads.emplace_back([=] { while (true) { Task task; { std::unique_lock<std::mutex> lock{mEventMutex}; mEventVar.wait(lock, [=] { return mStopping || !mTasks.empty(); }); if (mStopping && mTasks.empty()) break; task = std::move(mTasks.front()); mTasks.pop(); } task(); } }); } } void stop() noexcept { { std::unique_lock<std::mutex> lock{mEventMutex}; mStopping = true; } mEventVar.notify_all(); for (auto &thread : mThreads) thread.join(); } }; void foo(int num) { std::cout << "Thread " << std::this_thread::get_id() << " executing foo(" << num << ")" << std::endl; } int main() { ThreadPool pool{4}; for (int i = 0; i < 8; ++i) { pool.enqueue([=] { foo(i); }); } return 0; } ``` 在这个例子,我们定义了一个线程池 `ThreadPool`,它接受一个 `numThreads` 参数,表示线程池工作的线程数。线程池的每个线程都会不断地从任务队列取出任务,并执行任务。 我们还定义了一个 `Task` 类型,它是一个函数对象类型,可以封装任何可调用对象。 在 `ThreadPool` ,我们定义了一个 `enqueue` 函数模板,它接受一个可调用对象 `task`,将其封装成一个 `Task` 对象,并将其提交给任务队列。该函数返回一个 `std::future` 对象,用于获取任务的返回值。 在 `main` 函数,我们创建了一个线程池,并提交了 8 个任务到线程池。每个任务都是一个 lambda 函数,用于调用函数 `foo`,并传递一个整数参数。函数 `foo` 将在线程池的一个线程执行,并打印输出。 需要注意的是,由于线程池线程是异步执行的,因此 `foo` 函数的输出顺序可能会与任务提交的顺序不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值