当前位置:  技术问答>linux和unix

(急求解答)多个生产者和多个消费者出现问题

    来源: 互联网  发布时间:2017-04-29

    本文导语:  头文件Queue.h #include  #include  #include  #include  typedef int DataType; /*定义消费结束标志*/ #define OVER -1 /*定义队列数据结构*/ typedef struct _Queue { DataType data; struct _Queue *next; pthread_mutex_t lock; /* 互斥体lock 用于对...

头文件Queue.h
#include 
#include 
#include 
#include 

typedef int DataType;

/*定义消费结束标志*/
#define OVER -1

/*定义队列数据结构*/
typedef struct _Queue
{
DataType data;
struct _Queue *next;
pthread_mutex_t lock; /* 互斥体lock 用于对缓冲区的互斥操作 */
    pthread_cond_t notempty; /* 缓冲区非空的条件变量 */
}QueueNode, *Queue;

/*定义数据操作*/
void queue_init(Queue *queue_head);
int queue_is_empty(Queue queue_head);
int queue_insert(Queue queue_head, DataType value);
int queue_delete(Queue queue_head);
void queue_destory(Queue queue_head);


C文件 Queue.c
#include 
#include 
#include 
#include 
#include 
#include "Queue.h"                /*包含队列定义头文件*/

/*队列的初始化*/
void queue_init(Queue *queue_head)
{
/*队列的头节点*/
*queue_head = (QueueNode*)malloc(sizeof(QueueNode));
if (*queue_head == NULL)
{
perror("memory allocation failure");
return;
}
/*头节点用于记录队列中的节点个数*/
(*queue_head) -> data = 0;
/*circle list*/
/*初始时队列为空(只有一个节点)*/
(*queue_head) -> next = *queue_head;
}

/*判断队列是否为空*/
int queue_is_empty(Queue queue_head)
{
return queue_head -> data == 0 ? 1 : 0;
}

/*向队列中插入元素(生产者)*/
int queue_insert(Queue queue_head, DataType value)
{
QueueNode *new_node = NULL;
QueueNode *temp = NULL;
temp = queue_head;

/*首先获取队列的锁*/
pthread_mutex_lock(&queue_head -> lock);

new_node = (QueueNode*)malloc(sizeof(QueueNode));
if (new_node == NULL)
{
perror("memory allocation failure");
return -1;
}
/*初始化新节点*/
new_node -> data = value;
new_node -> next = queue_head;

/*采用头插法向队列中插入新节点*/
while (temp -> next != queue_head)
temp = temp -> next;
temp -> next = new_node;
queue_head -> data++;
printf("producer ----> %dn", value);

/*信号表明队列不为空*/
    pthread_cond_signal(&queue_head -> notempty);
    /*释放锁*/
    pthread_mutex_unlock(&queue_head -> lock);
    usleep(1);
    //usleep(300 * 1000);
return 0;
}

/*删除队列中的节点(消费者)*/
int queue_delete(Queue queue_head)
{
QueueNode *old_node = NULL;
DataType queue_value;

if (queue_head == NULL)
{
return -2;
}
/*获取队列锁*/
pthread_mutex_lock(&queue_head -> lock);
/*如果队列为空,则需要等待(线程睡眠,并释放锁)*/
if (queue_is_empty(queue_head))
{
pthread_cond_wait(&queue_head -> notempty, &queue_head -> lock);
}

/*队列不为空之后删除队列中的元素*/
old_node = queue_head -> next;
queue_head -> next = queue_head -> next -> next;
queue_head -> data--;

if (old_node != NULL)
{
queue_value = old_node -> data;
printf("%d ----> consumern", queue_value);
free(old_node);
old_node = NULL;
}
/*释放锁*/
    pthread_mutex_unlock(&queue_head -> lock);
    usleep(1);
    //usleep(600 * 1000);
return queue_value;
}

/*销毁队列*/
void queue_destory(Queue queue_head)
{
QueueNode *temp = NULL;
QueueNode *del_node = NULL;
if (queue_head == NULL)
{
return;
}
temp = queue_head -> next;
/*从队列头开始依次删除队列中的各个节点*/
while (temp != queue_head)
{
del_node = temp;
temp = temp -> next;
free(del_node);
}
free(queue_head);
queue_head = NULL;
return;
}



测试文件pro_con.c
#include 
#include 
#include 
#include 
#include 
#include 
#include "Queue.h"

/*生产者生产总数*/
#define PRO_NUM 10000

int flag = 1;

/*模拟生产者和消费者*/
void* producer(void *data);
void* consumer(void *data);
void* producer2(void *data);


Queue queue_head = NULL;

int main(int argc, char **argv)
{
pthread_t th_a, th_b;
pthread_t th_c, th_d;

    void *retval;
struct  timeval  start;
struct  timeval  end;
    unsigned long timer;

queue_init(&queue_head);
if (queue_head == NULL)
{
perror("memory allocation failure");
return -1;
}
gettimeofday(&start,NULL);
    /* 创建生产者和消费者线程*/
    pthread_create(&th_a, NULL, producer, 0);
    usleep(10);
    pthread_create(&th_b, NULL, consumer, 0);
    
    pthread_create(&th_c, NULL, producer2, 0);
    usleep(10);
    pthread_create(&th_d, NULL, consumer, 0);
    
    /* 等待两个线程结束*/
    pthread_join(th_a, &retval);
    pthread_join(th_b, &retval);
    
    pthread_join(th_c, &retval);
    pthread_join(th_d, &retval);
    
gettimeofday(&end,NULL);

/*得到的时间是微秒级*/
timer = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
    printf("timer = %ld usn",timer);

return 0;
}

void* producer(void *data)
{
int i = 1;

for (i = 1; i  lock);
 
    new_node = (QueueNode*)malloc(sizeof(QueueNode));
    if (new_node == NULL)
    {
        perror("memory allocation failure");
       
        pthread_mutex_unlock(&queue_head -> lock);  
       //失败的时候这句也是需要的!前面枷锁了,后面不管什么情况,都是需要解锁的!
        return -1;
    }
    

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 请路人甲来领分.谢谢你关于浏览器模态对话框的解答.
  • ChrisZhang(西楼明月),多谢你的解答。补送20分。
  • 一个奇怪的错误,请高手解答
  • WEB前端 iis7站长之家
  • 求高手解答菜鸟问题!!
  • gcc-plugin.h的问题,求解答。。。
  • 虚拟机里linux系统下输入l,k,m三个字母不能正常显示,求解答
  • 救命啊,高手解答,分不够再加
  • 一个相当实际的问题,希望来解答!
  • 紧急求援,限时解答(3小时内给分)
  • 大家都懒的回答我的吗?有人解答的话,送分100
  • 方法中的return()是返回到何处的,如何能获得,请解答
  • 有谁帮我解答一下?
  • 看看哪位高人能解答?
  • 新手关于Jbuilder6.0编辑器的光标定位使用问题,望高手解答
  • 真诚希望高手给予解答,关于UNIX扩展缓存的问题(100分相送)
  • 希望斑竹帮助解答!!在线等待
  • 能解答很多人疑问的好东西.
  • Redhat8.0中的乱码问题?(急需解答)
  • 简单的问题,请高手解答


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,