多线程与循环队列

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

多线程使用循环队列主要就是要避免两个线程同时操作队列,加个锁就可以很容易的实现,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

时间: 2024-10-02 05:06:55

多线程与循环队列的相关文章

数据结构Java实现07----队列:顺序队列&amp;顺序循环队列、链式队列、顺序优先队列

数据结构Java实现07----队列:顺序队列&顺序循环队列.链式队列.顺序优先队列 一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作. 队列中允许进行插入操作的一端称为队尾,允许进行删除操作的一端称为队头.队列的插入操作通常称作入队列,队列的删除操作通常称作出队列. 下图是一个依次向队列中插入数据元素a0,a1,...,an-

iOS多线程中,队列和执行的排列组合结果分析

本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到这边文章请 点击查看原文 提到多线程,也就是四种,pthread,NSthread,GCD,NSOperation 其中phtread是跨平台的.GCD和NSOperation都是常用的,后者是基于前者的. 但是两者区别:GCD的核心概念是将一个任务添加到队列,指定任务执行的方法,然后执行. NSO

多线程13-阻塞队列

1. 概念 阻塞队列的概念和前面提到的缓冲区的概念类似,常见一个固定长队的队列 ,如果队列满的时候 put数据则一致会阻塞等待,直到队列数据被取走后会立即执行put数据操作 同样的道理,如果队列为空时进行取数据take操作,则一直会阻塞等待,知道有线程执行了put数据到队列中后才会立即执行take数据的操作. 2.代码 package org.lkl.thead.foo; import java.util.Random; import java.util.concurrent.ArrayBloc

数据结构之循环队列c语言实现

    队列是一种先入先出的结构,数据从队列头出,队尾进.在linux内核中进程调度,打印缓冲区都有用到队列.     队列有多种实现方式,可以用链表,也可以用数组.这里用数组来实现一个简单的循环队列.首先创建一个大小为8的队列如下,队列头尾指针指向同一块内存,          当从队列尾部插入一个数据后变成下面的情形,为了便于处理,这里始终会浪费一个空间 继续插入数据,直到出现以下情形,表示队列满了, 接下来看一下出队的情形,从队列头出队3个元素, 再添加三个元素后队列又变成满的了, 在上面

47 _ 循环队列程序演示.swf

通过上面的分析我们已经对循环队列很了解了,现在我们来学习下循环队列的实现形式 1.代码使用数组现实循环队列 #include<stdio.h> #include<malloc.h> #include <stdio.h> #include <stdlib.h> typedef struct Queue{ int * data;//存储的数据,指向一个数组 int font ;//队列数据删除 int rear;//队列数据的添加 }QUEUE ,*PQUEUE

每日一题19:循环队列

基于数组实现的循环队列,这个比基于链表实现的稍微麻烦一点,需要浪费一个存储空间.如果全部利用,则编程将会变得更加繁琐,并且更容易出错. // LoopQueue.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using namespace std; struct loop_queue { int capacity; int head; int tail; int *vals; }; loop_

(一)循环队列

队列可以使用数组或者链表实现,这里介绍一种使用数组实现的循环队列. 所谓循环队列,是指当尾指针超过数组索引界限时,通过取余运算返回数组起始端,只要保证尾指针和头指针不相遇,就可以继续存储元素. 首先设定队列的大小,并建立队列结构体: #define MAXSIZE 100001 typedef struct { int items[MAXSIZE]; int front; int rear; }Queue; 设头指针和尾指针指向同一索引时队列为空,起始时均在索引0处. void initQueu

hdu 1175 连连看(模拟循环队列)

连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18149    Accepted Submission(s): 4741 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条

数据结构6_顺序队列(循环队列)

本文实现了顺序队列,与链队列不同的是,顺序队列需要考虑一个问题, 问题情况如下, 解决办法:循环队列,当rear到分配的数组空间末尾时,转到数组头 但是当q.rear==q.front时,又如何区分一种是空队列,一种是满队列的情况呢 这里有两种方案 本次代码实现了第一种方法,同时设置了一个技术变量length,稍加改动便可实现第二个方法 代码如下: #include<iostream>using namespace std;//该顺序队列为循环队列,解决队尾指针达到最大值,队列中有空闲单元,但