关于线程的一些简单案例

1、多线程判断质数

#define MAXNUM 1000
#define MAXTHREADS 5

vector<int> prime;
mutex mtx;
bool _isPrime(int n)
{
	if (n < 2) return false;
	for (int i = 2; i*i <= n; ++i)
	{
		if (n%i == 0)
		{
			return false;
		}
	}
	return true;
}

void isPrime(int a, int n)
{
	int i = 0;
	while (i < n)
	{
		if (_isPrime(a))
		{
			{
				lock_guard<mutex> lock(mtx);
				prime.push_back(a);
			}
		}
		a++;
		i++;
	}
}

int main()
{
	vector<thread> threads;
	for (int i = 0; i < MAXTHREADS; ++i)
	{
		threads.emplace_back(isPrime, i*(MAXNUM / 5) + 1, (MAXNUM / 5));
	}
	for (int i = 0; i < MAXTHREADS; ++i)
	{
		if (threads[i].joinable())
		{
			threads[i].join();
		}
	}
	cout << prime.size() << endl;
	for (size_t i = 0; i < prime.size(); ++i)
	{
		cout << prime[i] << " ";
	}
	cout << endl;
	return 0;
}

2、多线程交替打印ABC

mutex mtx;
condition_variable_any cv;
int flag = 0;

void printa()
{
	while (true)
	{
		unique_lock<mutex> lock(mtx);
		if(flag != 0)
			cv.wait(lock);
		else
		{
			cout << "thread 1:a" << endl;
			this_thread::sleep_for(chrono::seconds(1));
			flag = 1;
			cv.notify_all();
		}
	}
}

void printb()
{
	while (true)
	{
		unique_lock<mutex> lock(mtx);
		//条件为true,则继续向下执行,否则阻塞
		cv.wait(mtx, [] {
			return flag == 1;
		});
		cout << "thread 2:b" << endl;
		this_thread::sleep_for(chrono::seconds(1));
		flag = 2;
		cv.notify_all();
	}
}

void printc()
{
	while (true)
	{
		unique_lock<mutex> lock(mtx);
		if (flag != 2)
			cv.wait(lock);
		else
		{
			cout << "thread 3:c" << endl;
			this_thread::sleep_for(chrono::seconds(1));
			flag = 0;
			cv.notify_all();
		}
	}
}

int main()
{
	vector<thread> threads;
	threads.emplace_back(printa);
	threads.emplace_back(printb);
	threads.emplace_back(printc);
	for (int i = 0; i < 3; ++i)
	{
		if (threads[i].joinable())
		{
			threads[i].join();
		}
	}
	return 0;
}

3、生产者消费者模型

mutex mtx;
condition_variable_any notEmpty;//没满的条件变量
condition_variable_any notFull;//没空的条件变量
list<string> list_;
const int max_size = 10;

void custome(int i)
{
	while (true)
	{
		lock_guard<mutex> lock(mtx);
		notFull.wait(mtx, []() {
			return !list_.empty();
		});
		//this_thread::sleep_for(chrono::seconds(1));
		cout << "消费者" << i << "消费了" << list_.front() << endl;
		list_.pop_front();
		notEmpty.notify_one();
	}
}

void produce(int i)
{
	while (true)
	{
		lock_guard<mutex> lock(mtx);
		notEmpty.wait(mtx, []() {
			return list_.size() != max_size;
		});
		//this_thread::sleep_for(chrono::seconds(1));
		stringstream ss;
		ss << "生产者" << i << "生产的东西";
		list_.push_back(ss.str());
		notFull.notify_one();
	}
}

int main()
{
	vector<thread> producer;
	vector<thread> customer;
	for (int i = 0; i < 3; ++i)
	{
		producer.emplace_back(produce, i);
	}

	for (int i = 0; i < 3; ++i)
	{
		customer.emplace_back(custome, i);
	}

	for (size_t i = 0; i < producer.size(); ++i)
	{
		producer[i].join();
	}

	for (size_t i = 0; i < customer.size(); ++i)
	{
		customer[i].join();
	}
	return 0;
}

4、简易线程池

class ThreadPool
{
public:
	ThreadPool(size_t coreThreadSize, size_t maxThreadsSize, size_t maxQueueSize_)
	:coreThreadSize_(coreThreadSize), maxThreadsSize_(maxThreadsSize), maxQueueSize_(maxQueueSize_)
	{
		StartCoreThreads();
	}
	~ThreadPool()
	{
		Shutdown();
	}

	void Shutdown()
	{
		//修改标志位
		{
			std::unique_lock<std::mutex> lock(mutex_);
			isShutdown_ = true;
		}
		//唤醒所有线程,并等待
		condition_.notify_all();
		for (std::thread& thread : coreThreads_)
		{
			if (thread.joinable())
			{
				thread.join();
			}
		}
		coreThreads_.clear();
		std::cout << "线程池销毁" << std::endl;
	}


	void Submit(std::function<void()>&& task)
	{
		{
			std::unique_lock<std::mutex> lock(mutex_);
			//任务队列满了,添加失败
			if (taskQueue_.size() >= maxQueueSize_ || isShutdown_)
			{
				std::cerr << "Task queue is full, task submission failed" << std::endl;
				return;
			}
			//没满就插入,并随机唤醒一个正在等待的线程
			taskQueue_.emplace(std::move(task));
			
		}
		condition_.notify_one();

		{
			std::unique_lock<std::mutex> lock1(nocoreThreadMutex_);
			//如果任务队列已满并且线程数没达到最大值,就创建非核心线程
			if (taskQueue_.size() >= maxQueueSize_ && (coreThreads_.size() + nocoreThreadsSize_) < maxThreadsSize_)
			{
				std::cout << "创建非核心线程" << std::endl;
				thread t(&ThreadPool::StartNewThread, this, false);
				t.detach();
				nocoreThreadsSize_++;
			}
			else
			{
				std::cout << "task not is full" << std::endl;
			}
		}
	}

private:
	void StartCoreThreads()
	{
		for (size_t i = 0; i < coreThreadSize_; ++i)
		{
			coreThreads_.emplace_back(&ThreadPool::StartNewThread, this, true);
		}
	}
	void StartNewThread(bool coreThread)
	{
		while (true)
		{
			std::function<void()> task;
			{
				std::unique_lock<std::mutex> lock(mutex_);
				//如果任务队列为空并且当前线程为非核心线程
				if (taskQueue_.empty() && !coreThread)
				{
					break;
				}
				condition_.wait(lock, [&] {
					return isShutdown_ || !taskQueue_.empty();
				});
				//标志位为true并且任务队列为空
				if (isShutdown_ && taskQueue_.empty())
				{
					break;
				}
				task = taskQueue_.front();
				taskQueue_.pop();
			}
			if (task) task();
		}

		if (!coreThread)
		{
			{
				std::unique_lock<std::mutex> lock1(nocoreThreadMutex_);
				nocoreThreadsSize_--;
				cout << "非核心线程销毁 " << nocoreThreadsSize_ << endl;
			}
		}

	}


	size_t coreThreadSize_;	//核心线程数
	size_t maxThreadsSize_;		//最大线程数
	size_t maxQueueSize_;	//最大任务数
	std::queue<std::function<void()>> taskQueue_;	//任务队列
	std::vector<std::thread> coreThreads_;		//核心线程
	size_t nocoreThreadsSize_ = 0;	//非核心线程数
	std::mutex mutex_;
	std::mutex nocoreThreadMutex_;
	std::condition_variable_any condition_;
	bool isShutdown_ = false;	//表示是否退出
};

void func()
{
	std::cout << "正在工作" << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(5));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值