c++11 跨平台线程池

线程的反复开辟和销毁都是一个十分消耗资源和时间的事,

线程池可以提前开辟好线程保存在线程池当中,当有任务的时候,从线程池中取线程,执行完成任务后然会把他放回线程池,等待下次使用

生产者消费者模型

代码实现

#include"iostream"
#include"mutex"
#include"thread"
#include"string"
#include"condition_variable"
#include"queue"
#include"functional"
#include"vector"
class TreadPool;

class ThreadPool {
public:
	ThreadPool(int numThreads): stop(false)
	{
		for (int i = 0; i < numThreads; i++)
		{    //加线程,判断队列里面是否有任务,有就去完成
			threads.emplace_back([this]() {//empalce_back函数,线程直接构造,避免复制和移动,节省资源
				while (1)
				{
					std::unique_lock<std::mutex> lock(mtx);//1加锁
					//2等待
					condition.wait(lock, [this]() {
						return  ! tasks.empty() || stop; 
						});
					//主线程结束,直接终止
					if (stop&&tasks.empty())
					{
						return;
					}
					//3取任务
					std::function<void()>task(std::move(tasks.front()));
					tasks.pop();
					lock.unlock();
					task();
				}

				});
		}
	}
	~ThreadPool() {
		{
			std::unique_lock<std::mutex>lock(mtx);//stop也是多线程去访问的一个变量,我们要加锁
			stop = true;//
		}
		condition.notify_all();//为true的时候要通知把线程把所有任务完成
		for (auto&t:threads)
		{
			t.join();
		}
	}
	template<class F,class... Args>  //F为函数  ,args 为要传入的参数


	void enqueue(F&& f,Args&&...args) {//函数模板里的右值引用是万能引用,如果是右值引用就取右,左就取左
		std::function<void()>task =
			std::bind(std::forward<F>(f),std::forward<Args>(args)...);//用bind进行函数和参数绑定//forward进行完美转发  左值引用传左引,右引传右引
		{  
			std::unique_lock<std::mutex>lock(mtx); //对于共享变量一定要,一点要加锁
		    tasks.emplace(std::move(task));//如果是左值,把左值转换成右值再加进去  emplace可以传右值,直接占用右值资源不必拷贝
		}//加作用域,只有失去作用域才会调用析构函数,然后解锁
		condition.notify_one();//加了任务一定要通知线程来完成


	}                                                                                     
private:
	std::vector<std::thread>threads;//线程池
	std::queue<std::function<void()>>tasks;//任务队列

	std::mutex mtx;
	std::condition_variable condition;//条件变量

	bool stop;
};
void main()

{

	ThreadPool pool(4);
	for (int i = 0; i <10;i++)
	{
		pool.enqueue([i] {
		std::cout << "task:" << i << "is Running" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(1));
		std::cout << "task:" << i << "is Down" << std::endl;
	   });
	}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt线程池是Qt提供的一种管理线程的机制,它可以帮助我们更有效地利用系统资源,并方便地进行多线程编程。 Qt线程池中的线程是共享的,这意味着多个任务可以在同一个线程中执行。线程池内部会维护一组可用的线程,当有任务需要执行时,会选择一个空闲的线程来执行任务。通过共享线程的方式,线程池可以减少线程创建和销毁的开销,提高线程的复用性。 在使用Qt线程池时,我们可以将一些待执行的任务(比如耗时的计算、网络请求等)封装成QRunnable对象,并将其提交给线程池线程池会自动将这些任务分配给空闲线程执行,而不需要我们手动创建和管理线程。 线程池的共享机制可以提高程序的性能和响应速度。通过共享线程,线程池可以更好地管理线程的数量,避免过多的线程创建和销毁过程,从而减少了系统资源的消耗。而且,线程池可以实现任务的并行执行,提高任务处理的效率。 不过需要注意的是,在使用Qt线程池的过程中,我们需要在处理任务时保证线程安全。由于线程池中的线程是共享的,多个任务可能会同时在同一个线程中执行。因此,如果任务之间有共享的数据,必须使用互斥锁等机制来保护共享数据的访问,防止出现数据竞争和异常行为。 总而言之,Qt线程池提供了一种方便且高效的多线程编程机制,通过线程共享的方式减少了线程创建和销毁的开销,提高了程序的性能和响应速度。同时,我们需要注意线程安全性,在处理共享数据时使用适当的同步机制。 ### 回答2: 在Qt中,线程池是一种用于管理和调度线程的机制,它能够实现线程的复用,提高多线程编程的效率。线程池可以用于并行执行多个任务,每个任务由一个线程来处理。 Qt的线程池使用QThreadPool类来实现,它提供了一组方法来管理线程池的大小、任务的提交和取消等操作。线程池中的线程是由Qt框架自动创建和管理的,可以通过设置线程池大小来控制线程的数量。线程池中的线程是共享的,即多个任务可以被同一个线程处理。 线程池的共享性能够节省资源,避免为每个任务都单独创建和销毁线程,从而减少了线程切换的开销。在每个任务执行完成后,线程会自动归还给线程池,以便被下一个任务使用。这样一来,线程池中的线程可以被多个任务共享,从而提高了系统的并发性能。 线程池的共享特性还可以通过Qt中的信号与槽机制实现线程间的通信。例如,一个任务在执行过程中需要与其他线程进行数据交换,可以通过发送信号和槽的方式实现线程间的消息传递。 总之,Qt的线程池可以实现线程的复用和共享,提高多线程编程的效率和性能。它是一种非常实用的多线程技术,适用于需要并行执行多个任务的场景。 ### 回答3: Qt是一个跨平台C++开发库,提供了线程池和线程共享的功能。 线程池是一种线程管理机制,它维护一个线程的集合,以便在需要的时候可以复用这些线程,而不需要显式地创建和销毁线程。Qt提供了QThreadPool类,它可以用于创建和管理线程池。通过使用线程池,可以更方便地处理并发任务,提高应用程序的性能和响应能力。 线程共享是指多个线程可以同时访问和修改共享的数据。在多线程编程中,线程之间共享的数据可能存在竞争条件和数据不一致的问题。为了避免这些问题,Qt提供了一些线程同步和互斥的机制。比如使用QMutex和QMutexLocker可以控制对临界区的访问,一次只允许一个线程进入;使用QReadWriteLock可以实现读写线程之间的互斥;使用QWaitCondition可以实现线程之间的条件等待和通知。 在Qt中,线程池和线程共享是可以同时使用的。线程池可以创建多个线程,并管理它们的执行,而线程之间可以共享数据,并使用适当的线程同步机制来保证数据的一致性。通过合理地使用线程池和线程共享,可以提高应用程序的并发性能,提升用户体验。同时,Qt提供了丰富的线程管理和同步机制,使得多线程编程更加简单和可靠。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值