• 多线程与循环队列


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

        多线程使用循环队列主要就是要避免两个线程同时操作队列,加个锁就可以很容易的实现,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 
    ",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 
    ",tar) ;
        }
    
        return 0;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        q = (Queue *)malloc(sizeof(Queue));
        initQueue(q);
    
        printf("-----------start-------------- 
    ") ;
        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-------------- 
    ") ;
        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
    ");
        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

  • 相关阅读:
    我的 conky 配置 (入门)
    三个字符编码问题的解决
    如何查看Mysql的版本
    oracle历险记纪实
    禁用USB总集
    如何更改Andrioid模拟器 avd路径
    linux 安装rpm包时遇到error:Failed dependencies解法方法
    最为流行的几款Java IDE
    android sdk 如何重新生成debug.keystore
    开始学习linux知识,每天做点总结
  • 原文地址:https://www.cnblogs.com/betterwgo/p/6238353.html
Copyright © 2020-2023  润新知