多线程与循环队列

Posted 啊基米舍的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程与循环队列相关的知识,希望对你有一定的参考价值。

    多线程使用循环队列其实也不是个很难的东西,在工作中遇到了一个队列行为非常古怪,怎么也想不通,一直都没有认证对待这些,有点怵,所以这回想认真对待一下。

    多线程使用循环队列主要就是要避免两个线程同时操作队列,加个锁就可以很容易的实现,win32中用临界区就可以做到。

代码:

// CirQueue.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

#define MAXSIZE 10

typedef struct Queue{
    int data[MAXSIZE];
    int front;
    int rear;
    int size ;
    CRITICAL_SECTION cs ;
}Queue;

void initQueue(Queue *q);
void showQueue(Queue *q);
int inQueue(Queue *q,int num);
int outQueue(Queue *q);
void deQueue(Queue *q) ;

Queue *q ;

DWORD WINAPI ThreadFuncFirst(LPVOID param)
{
    int iCount = 0;
    while(iCount < 60){
        if (!inQueue(q,iCount))
        {
            Sleep(10) ;
            continue ;
        }
        printf("inQueue = %d \n",iCount) ;
        iCount ++  ;
    }
    return 0;
}

DWORD WINAPI ThreadFuncSecond(LPVOID param)
{
    int iCount = 60;
    int tar ;
    while(iCount > 0){
        iCount-- ;
        tar = outQueue(q) ;
        if (tar < 0)
        {
            Sleep(10) ;
            continue ;
        }
        printf("outQueue = %d \n",tar) ;
    }

    return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
    q = (Queue *)malloc(sizeof(Queue));
    initQueue(q);

    printf("-----------start-------------- \n") ;
    DWORD dwThreadID = 0;
    HANDLE handleFirst = CreateThread(NULL, 0, ThreadFuncFirst, 0, 0, &dwThreadID);
    if (!handleFirst)
    {
        cout<<"create thread 1 error:"<<endl;
    }
    HANDLE handleSecond = CreateThread(NULL, 0, ThreadFuncSecond, 0, 0, &dwThreadID);
    if (!handleSecond)
    {
        cout<<"create thread 2 error:"<<endl;
    }

    WaitForSingleObject(handleFirst, INFINITE);//等待线程返回,用sleep()就太山寨了
    WaitForSingleObject(handleSecond, INFINITE);
    CloseHandle(handleFirst);//句柄默认值2 这里减1,线程函数执行完后释放资源。
    CloseHandle(handleSecond);

    deQueue(q) ;

    printf("-----------end-------------- \n") ;
    system("pause") ;
    return 0;
}

void initQueue(Queue *q){
    int i;
    for(i=0;i<MAXSIZE;i++){
        q->data[i]= -111 ;
    }
    q->front=0;
    q->rear =0;
    q->size = 0 ;
    InitializeCriticalSection(&q->cs) ;
}
void showQueue(Queue *q){
    EnterCriticalSection(&q->cs) ;
    printf("front-");
    int len = q->size ;
    for(int i=0;i<len;i++){
        if(q->front+i<MAXSIZE)
            printf("%d-",q->data[q->front+i]);
        else
            printf("%d-",q->data[q->front+i-MAXSIZE]);
    }
    printf("rear\n");
    LeaveCriticalSection(&q->cs) ;
}
int inQueue(Queue *q,int num){
    int ret = 1 ;
    EnterCriticalSection(&q->cs) ;
    if(q->size >= MAXSIZE)
    {
        ret = 0;
    }
    else
    {
        q->data[q->rear] = num;
        q->size ++ ;
        q->rear = (q->rear+1)%MAXSIZE;
    }
    LeaveCriticalSection(&q->cs) ;
    return ret;
}
int outQueue(Queue *q){
    int num = -1 ;
    EnterCriticalSection(&q->cs) ;
    if(q->size <= 0)
    {
        num = -1;
    }
    else
    {
        num = q->data[q->front];
        q->size -- ;
        q->front = (q->front+1)%MAXSIZE;
    }
    LeaveCriticalSection(&q->cs) ;
    return num;
}

void deQueue(Queue *q)
{
     free(q) ;
}

代码中,一个线程向队列中写数据,另一个从队列中读数据,队列的结构体有成员CRITICAL_SECTION cs ; 用来防止两个队列同时对队列进行访问。

 

完整工程代码:http://download.csdn.net/download/qq_33892166/9725911

以上是关于多线程与循环队列的主要内容,如果未能解决你的问题,请参考以下文章

一篇搞定(Js异步事件循环与消息队列微任务与宏任务)

一篇搞定(Js异步事件循环与消息队列微任务与宏任务)

TWEN-ASR ONE 语音识别系列教程---多线程与消息队列使用

TWEN-ASR ONE 语音识别系列教程---多线程与消息队列使用

TWEN-ASR ONE 语音识别系列教程---多线程与消息队列使用

TWEN-ASR ONE 语音识别系列教程---多线程与消息队列使用