题目:实现一个队列
队列的应用场景为:
一个生产者线程将int类型的数入列,一个消费者线程将int类型的数出列。
分析:
首先得设计一个队列,并且最好是循环队列,否则队列里面的空间很容易一下就使用完了。
题目要求使用生产者线程和消费者线程,所以得设计成线程保护,否则取数据和推送数据很容易搞错。可以使用线程的互斥变量:pthread_mutex_t
加pthread_mutex_lock 锁,解锁:pthread_mutex_unlock
比如:生产者线程每隔1s推送:1,2,3,4,5,6,7,8,9,10这10个数字到队列中,消费者每隔2s从这个队列中取1个数字,直到取完为止。
实现如下:
#include<iostream> #include<pthread.h> using namespace std; template <typename T, int SIZE=1024> class CircularQueue { public: T queue[SIZE]; int begin, end; CircularQueue():begin(0),end(0) { } ~CircularQueue(){} bool empty() { return begin == end; } bool full() { return (end + 1)%SIZE == begin; } void waitFull() { int st = 1; while (full()) { usleep(st); st = min(1000, st*2); } } void waitEmpty() { int st = 1; while (empty()) { usleep(st); st = min(1000, st*2); } } void push(const T& t) { waitFull(); queue[end] = t; end = (end + 1)%SIZE; } bool pop(T& t) { //waitEmpty(); if(empty()) return false; t = queue[begin]; begin = (begin + 1)%SIZE; return true; } /* T pop() { T t; return pop(t); } */ }; template <typename T, int SIZE = 1024> class LockedQueue { CircularQueue<T, SIZE+1> cq; pthread_mutex_t mutex; public: LockedQueue() { cq.begin = 0; cq.end = 0; pthread_mutex_init(&mutex, NULL); } ~LockedQueue() { pthread_mutex_destroy(&mutex); } void push(const T& t) { pthread_mutex_lock(&mutex); cq.push(t); pthread_mutex_unlock(&mutex); } bool pop(T& t) { pthread_mutex_lock(&mutex); bool bp = cq.pop(t); pthread_mutex_unlock(&mutex); if(!bp) return false; return true; } /* T pop() { T t; pop(t); return t; }*/ }; void *product_function(void *arg) { LockedQueue<int, 1024>* flq = (LockedQueue<int, 1024>*)arg; int i = 0; while(i < 10) { i ++; flq->push(i); cout << "product: " << i << endl; sleep(1); } } void *consume_function(void *arg) { LockedQueue<int, 1024>* flq = (LockedQueue<int, 1024>*)arg; while(1) { int a = 0; sleep(2); if(flq->pop(a)) cout << "consume: " << a << endl; else cout << "queue empty!" << endl; if(a >= 10) break; } } int main() { //test productor, consumor pthread_t thread1, thread2; LockedQueue<int, 1024> lq; pthread_create(&thread1, NULL, product_function, &lq); pthread_create(&thread2, NULL, consume_function, &lq); pthread_join(thread1, NULL); pthread_join(thread2, NULL); return 0; }
使用g++编译:
g++ 29.cpp -o 29 -lpthread
输出结果:product: 1
product: 2
consume: 1
product: 3
product: 4
consume: 2
product: 5
product: 6
consume: 3
product: 7
product: 8
consume: 4
product: 9
product: 10
consume: 5
consume: 6
consume: 7
consume: 8
consume: 9
consume: 10