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

题目:实现一个队列

队列的应用场景为:

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

作者:csdn博客 hhh3h

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索线程
, 队列
, return
, usleep
, 生产者
, mutex
, end
, ptread mutex t
, 多线程面试题
栈和队列面试题
,以便于您获取更多的相关知识。

时间: 2024-10-01 17:32:27

微软面试题解析:使用多线程实现一个队列的相关文章

微软面试题解析:实现一个挺高级的字符匹配算法

题目: 给一串很长字符串,要求找到符合要求的字符串,例如目的串:123 1******3***2 ,12*****3这些都要找出来 其实就是类似一些和谐系统. 分析: 自然匹配就是对待匹配的每个字符挨个匹配 设你的待匹配字串长度位n,模式字符串长度位m. 对于待匹配字符串中的任意一个字符最坏情况下要匹配m次,也就是说这个字符不在模式字符串中. 所以最坏情况下总共是m*n此匹配,时间复杂度就是O(m*n) 更多精彩内容:http://www.bianceng.cnhttp://www.biance

微软面试题解析:求一个矩阵中最大的二维矩阵(元素和最大)

题目:求一个矩阵中最大的二维矩阵(元素和最大).如: 1 2 0 3 4 2 3 4 5 1 1 1 5 3 0 中最大的是: 4 5 5 3 要求:(1)写出算法;(2)分析时间复杂度;(3)用C写出关键代码 分析: 直接遍历二维数组,求出最大的二维数组就OK了 实现如下: #include<iostream> using namespace std; int max_matrix(int (*array)[5], int maxx, int maxy, int& posi, int

微软面试题解析:整数的二进制表示中1的个数

题目:输入一个整数,求该整数的二进制表达中有多少个1. 例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 分析: 使用移位操作,来实现. 具体实现如下: #include<iostream> using namespace std; int binary1num(int d) { int cnt = 0; while(d/2 != 0) { if(d%2 == 1) cnt ++; d = d/2; } if(d%2 == 1) cnt ++; return cnt; } in

微软面试题解析:栈的push、pop序列(栈)

题目:输入两个整数序列.其中一个序列表示栈的push顺序, 判断另一个序列有没有可能是对应的pop顺序. 为了简单起见,我们假设push序列的任意两个整数都是不相等的. 比如: 输入的push序列是1,2,3,4,5 ,那么4,5,3,2,1就有可能是一个pop序列. 因为可以有如下的push和pop序列: push 1, push 2, push 3, push 4, pop, push 5, pop, pop, pop, pop 这样的的得到的pop序列就是4,5,3,2,1. 但是序列4,

微软面试题解析:调整数组顺序使奇数位于偶数前面(数组)

题目: 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分.要求时间复杂度为O(n). 分析: 只需要设置头尾两个指针遍历就可以了,前面遇到偶数记下来,后面遇到奇数记下来,交换,知道后面的指针小于前面的指针. 更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/ 实现如下: #include<iostream> #include<stdio.h> #

微软面试题解析:请修改append函数, 利用函数实现(链表)

题目: 请修改append函数,利用这个函数实现: 两个非降序链表的并集,1->2->3 和 2->3->5 并为 1->2->3->5 另外只能输出结果,不能修改两个链表的数据. 分析: 这题很简单,两个指向链表的指针,比较对应的值,并遍历 实现如下: #include<iostream> using namespace std; struct Node{ Node(int _v = 0):value(_v),next(NULL) {} int va

深入理解Js的This绑定 ( 无需死记硬背,尾部有总结和面试题解析 )

js 的 this 绑定问题,让多数新手懵逼,部分老手觉得恶心,这是因为this的绑定 '难以捉摸',出错的时候还往往不知道为什么,相当反逻辑. 让我们考虑下面代码: var people = {      name : "海洋饼干",      getName : function(){          console.log(this.name);      }  };  window.onload = function(){      xxx.onclick =  people

微软面试题:正则表达式提取链接地址

写出正则表达式,从一个字符串中提取链接地址.比如下面字符串中  "IT面试题博客中包含很多  <a href=http://hi.baidu.com/mianshiti/blog/category/微软面试题> 微软面试题 </a> "  则需要提取的地址为 " http://hi.baidu.com/mianshiti/blog/category/微软面试题 " 在python中:  import re  p = re.compile('&

XML指南——微软的XML解析器

    XML解析器可以读取.更新.创建.操作一个XML文档.使用XML解析器微软的XML解析器是和IE5.0+浏览器捆绑在一起的.一旦你安装了IE5.0,那么就获得了XML解析器.这个浏览器除了被浏览器内部调用外,还可以在脚本中或者程序中调用.这个解析器的特点是支持与程序设计语言无关的编程模型,他支持以下技术:JavaScript, VBScript, Perl, VB, Java, C++ 等等 W3C XML 1.0 和 XML DOM DTD 和 XML文档验证 如果浏览器使用JavaS