28. 微软面试题:使用多线程实现一个队列

题目:实现一个队列

队列的应用场景为:

一个生产者线程将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

28. 微软面试题:使用多线程实现一个队列,布布扣,bubuko.com

28. 微软面试题:使用多线程实现一个队列

上一篇:C++获取Windows时间的方法总结


下一篇:Spring MVC 初使用