1:写一个链表
2:如果超过固定大小push阻塞
3:如果链表为空,pop也会阻塞
直接看代码,
main.cpp
#include <stdio.h>
#include <list>
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
using namespace std;
class listPack
{
public:
listPack(int maxSize = 10)
{
this->_maxSize = maxSize;
}
~listPack()
{
// 释放链表
}
void push(int *mPkt) // 如果链表满,会阻塞
{
{
std::unique_lock<std::mutex> lock{ muxPktVideo };
conditionMax.wait(lock, [&]()->bool { return listPacks_video.size() < _maxSize; });
}
{
std::unique_lock<std::mutex> lock{ muxPktVideo };
listPacks_video.push_back(mPkt);
conditionVideo.notify_one();
}
}
int * pop() // 如果链表空,也会阻塞
{
int * t_pkt = 0;
{
std::unique_lock<std::mutex> lock{ muxPktVideo };
//MVideoCap * ptr = this;
conditionVideo.wait(lock, [&]()->bool { return listPacks_video.size() > 0; });
t_pkt = listPacks_video.front();
listPacks_video.pop_front();
conditionMax.notify_one();
}
return t_pkt;
}
private:
std::list <int *> listPacks_video;
std::mutex muxPktVideo;
std::condition_variable conditionVideo;
std::condition_variable conditionMax;
int _maxSize = 10; // 链表的最大长度, 如果等于10 push 的时候会阻塞, 如果等于0 get 的时候会阻塞
};
listPack mListPack(6);
void run(void *prt)
{
while (1)
{
printf("run .... \n");
int *p = mListPack.pop();
printf("p[0] = %d \n", p[0]);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
delete p;
}
}
int main()
{
std::thread th(run, (void*)(NULL));
for (int i = 0; i < 100; i++)
{
int * p = new int[1];
*p = i;
mListPack.push(p);
printf("hello i = %d \n", i);
}
th.join();
}
用模板来写这个链表类似乎更通用一些
main.cpp
#include <stdio.h>
#include <list>
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
using namespace std;
template<typename T>
class TaskQueueMax {
public:
TaskQueueMax(int maxSize=10)
{
this->_maxSize = maxSize;
}
//打入任务至列队
template<typename C>
void push_task(C &&task_func) {
{
unique_lock<decltype(_mutex)> lock{ _mutex };
_conditionMax.wait(lock, [&]()->bool { return _queue.size() < _maxSize; }); // suspend and wait ...
}
{
lock_guard<decltype(_mutex)> lock(_mutex);
_queue.emplace_back(std::forward<C>(task_func));
_condition.notify_one();
}
}
template<typename C>
void push_task_first(C &&task_func) {
{
unique_lock<decltype(_mutex)> lock{ _mutex };
_conditionMax.wait(lock, [&]()->bool { return _queue.size() < _maxSize; }); // suspend and wait ...
}
{
lock_guard<decltype(_mutex)> lock(_mutex);
_queue.emplace_front(std::forward<C>(task_func));
_condition.notify_one();
}
}
//清空任务列队
void push_exit(unsigned int n) {
}
//从列队获取一个任务,由执行线程执行
bool get_task(T &tsk) {
unique_lock<decltype(_mutex)> lock(_mutex);
_condition.wait(lock, [&]()->bool { return _queue.size() > 0; }); // suspend and wait ...
//改成右值引用后性能提升了1倍多!
tsk = std::move(_queue.front());
_queue.pop_front();
_conditionMax.notify_one();
return true;
}
uint64_t size() const {
lock_guard<decltype(_mutex)> lock(_mutex);
return _queue.size();
}
private:
std::list<T> _queue;
mutable mutex _mutex;
std::condition_variable _condition;
std::condition_variable _conditionMax;
int _maxSize;
};
TaskQueueMax<int *> mTaskQueue(10);
void run(void *prt)
{
while (1)
{
printf("run .... \n");
int * p = 0;
mTaskQueue.get_task(p);
printf("p[0] = %d \n", p[0]);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
delete p;
}
}
int main()
{
std::thread th(run, (void*)(NULL));
for (int i = 0; i < 100; i++)
{
int * p = new int[1];
*p = i;
mTaskQueue.push_task(p);
printf("hello i = %d \n", i);
}
th.join();
}
不限制链表长度
#include <stdio.h>
#include <list>
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
using namespace std;
template<typename T>
class TaskQueueMax {
public:
TaskQueueMax()
{
}
//打入任务至列队
template<typename C>
void push_task(C &&task_func) {
{
lock_guard<decltype(_mutex)> lock(_mutex);
_queue.emplace_back(std::forward<C>(task_func));
_condition.notify_one();
}
}
template<typename C>
void push_task_first(C &&task_func) {
{
lock_guard<decltype(_mutex)> lock(_mutex);
_queue.emplace_front(std::forward<C>(task_func));
_condition.notify_one();
}
}
//清空任务列队
void push_exit(unsigned int n) {
}
//从列队获取一个任务,由执行线程执行
bool get_task(T &tsk) {
unique_lock<decltype(_mutex)> lock(_mutex);
_condition.wait(lock, [&]()->bool { return _queue.size() > 0; }); // suspend and wait ...
//改成右值引用后性能提升了1倍多!
tsk = std::move(_queue.front());
_queue.pop_front();
return true;
}
uint64_t size() const {
lock_guard<decltype(_mutex)> lock(_mutex);
return _queue.size();
}
private:
std::list<T> _queue;
mutable mutex _mutex;
std::condition_variable _condition;
};
TaskQueueMax<int *> mTaskQueue;
void run(void *prt)
{
while (1)
{
printf("run .... \n");
int * p = 0;
mTaskQueue.get_task(p);
printf("p[0] = %d \n", p[0]);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
delete p;
}
}
int main()
{
std::thread th(run, (void*)(NULL));
for (int i = 0; i < 100; i++)
{
int * p = new int[1];
*p = i;
mTaskQueue.push_task(p);
printf("hello i = %d \n", i);
}
th.join();
}