一、题目要求
生产者消费者模型:在多线程下生产0~100个数,生产者线程1生产20个数据后,消费者线程1进行消费输出。
二、解答
使用到的技术:互斥锁、条件变量、多线程、双端队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| #if 1 #include<iostream> #include<deque> #include<mutex> #include<condition_variable> using namespace std;
mutex mtx; std::condition_variable cv;
class Queue { public: void PushData(int index, int val) { unique_lock<mutex> lock(mtx); cv.wait(lock, [this]()->bool {return qu.size() != 20; }); qu.push_back(val); cv.notify_all(); cout << "Producer:" << index << " " << "val:" << val << endl; } void PopData(int index) { unique_lock<mutex> lock(mtx); cv.wait(lock, [this]()->bool {return !qu.empty(); }); int val = qu.front(); qu.pop_front(); cv.notify_all(); cout << "Customer:" << index << " " << "val:" << val << endl; } private: deque<int> qu; }; void Producer(Queue& qu, int index) { for (int i = 0; i < 100; ++i) { qu.PushData(index, i); } } void Customer(Queue& qu, int index) { for (int i = 0; i < 100; ++i) { qu.PopData(index); } }
int main() { Queue qu; thread tha(Producer, std::ref(qu), 1); thread thb(Customer, std::ref(qu), 1);
tha.join(); thb.join(); return 0; } #endif
|
![在这里插入图片描述](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
三、题目要求
实现一个循环队列,生产者线程生产0~100, 每次最多生产8个,然后消费者线程进行输出使用。
根据锁的粒度分为:
- 行锁:并发性强,锁开销较大
- 表锁:并发性弱,锁开销较小
四、解答
(1)行锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| #if 1 #include<iostream> #define MAXSIZE 8 #include<mutex> #include<condition_variable>
using namespace std; template<class T> class Queue { public: Queue() :data(new T[MAXSIZE]), maxsize(MAXSIZE), front(0), rear(0), size(0) {} ~Queue() { if (nullptr != data) { delete data; } maxsize = -1; front = -1; rear = -1; size = -1; } bool Capacity()const { return maxsize; } bool Size()const { return size; } bool Empty()const { return size == 0; } bool Full()const { return size == maxsize; } bool Push_back(T& val) { if (Full()) return false; data[rear] = val; rear = (rear + 1) % maxsize; ++size; return true; } bool Pop_front(T& val) { if (Empty()) return false; val = data[front]; front = (front + 1) % maxsize; --size; return true; }
private: T* data; int maxsize; int size; int front; int rear; }; Queue<int> qu; std::mutex mtx; std::condition_variable cv; int number = 0; void Producer(int index) { for (int i = number; i < 100; ++i) { unique_lock<mutex> lock(mtx); cv.wait(lock, []()->bool {return !qu.Full(); }); qu.Push_back(i); cv.notify_all(); cout << "Producer:" << index <<" "<< "val:" << i << endl; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } void Customer(int index) { for (int i = number; i < 100; ++i) { unique_lock<mutex> lock(mtx); cv.wait(lock, []()->bool {return !qu.Empty(); }); int val = 0; qu.Pop_front(val); cv.notify_all(); cout << "Customer:" << index << " " << "val:" << val << endl; } } int main() { thread tha(Producer, 1); thread thb(Customer, 1); tha.join(); thb.join(); return 0; }
#endif
|
![在这里插入图片描述](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
(2)表锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #if 1 #include<iostream> #define MAXSIZE 8 #include<mutex> #include<condition_variable>
using namespace std; template<class T> class Queue { public: Queue() :data(new T[MAXSIZE]), maxsize(MAXSIZE), front(0), rear(0), size(0) {} ~Queue() { if (nullptr != data) { delete data; } maxsize = -1; front = -1; rear = -1; size = -1; } bool Capacity()const { return maxsize; } bool Size()const { return size; } bool Empty()const { return size == 0; } bool Full()const { return size == maxsize; } bool Push_back(T& val) { if (Full()) return false; data[rear] = val; rear = (rear + 1) % maxsize; ++size; return true; } bool Pop_front(T& val) { if (Empty()) return false; val = data[front]; front = (front + 1) % maxsize; --size; return true; }
private: T* data; int maxsize; int size; int front; int rear; };
Queue<int> qu; std::mutex mtx; std::condition_variable cv; int number = 0; void Producer(int index) { unique_lock<mutex> lock(mtx); for (int i = number; i < 100; ++i) { cv.wait(lock, []()->bool {return !qu.Full(); }); qu.Push_back(i); cv.notify_all(); cout << "Producer:" << index <<" "<< "val:" << i << endl; } } void Customer(int index) { unique_lock<mutex> lock(mtx); for (int i = number; i < 100; ++i) { cv.wait(lock, []()->bool {return !qu.Empty(); }); int val = 0; qu.Pop_front(val); cv.notify_all(); cout << "Customer:" << index << " " << "val:" << val << endl; } } int main() { thread tha(Producer, 1); thread thb(Customer, 1); tha.join(); thb.join(); return 0; }
|
![在这里插入图片描述](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)