Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1742972
  • 博文数量: 1493
  • 博客积分: 38
  • 博客等级: 民兵
  • 技术积分: 5834
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-19 17:28
文章分类

全部博文(1493)

文章存档

2016年(11)

2015年(38)

2014年(137)

2013年(253)

2012年(1054)

2011年(1)

分类:

2012-12-19 09:24:07

原文地址:单链表有锁队列实现 作者:jiuniu110

[root@TEST comm_queue]# cat queue.h

  1. #ifndef MP4_QUEUE_H
  2. #define MP4_QUEUE_H
  3. #include <assert.h>
  4. #include <pthread.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>

  7. typedef enum {
  8.         QUEUE_EMPTY,
  9.         QUEUE_REGULAR
  10. } queue_flag;

  11. typedef struct _qnode_t qnode_t;
  12. struct _qnode_t {
  13.     int fd;    
  14.     qnode_t *next;
  15. };

  16. typedef struct _queue_t queue_t;
  17. struct _queue_t {
  18.     qnode_t *head;
  19.     qnode_t *tail;
  20. };

  21. //extern queue_t queue;
  22. extern queue_flag queue_test(queue_t *queue);
  23. extern void enqueue(queue_t *queue, int fd);
  24. extern int dequeue(queue_t *queue);
  25. extern void traverse(queue_t *q);
  26. #endif
[root@TEST_190 comm_queue]# cat queue.c

  1. #include "queue.h"

  2. queue_flag queue_test(queue_t *queue)
  3. {
  4.     assert(queue);
  5.     if (queue->head == NULL)
  6.         return QUEUE_EMPTY;    
  7.     return QUEUE_REGULAR;
  8. }

  9. void enqueue(queue_t *queue,int fd)
  10. {
  11.     assert(queue);
  12.     qnode_t *node = NULL;
  13.     node = (qnode_t*)malloc(sizeof(qnode_t));
  14.     if (!node) {
  15.         perror("enqueue malloc error:\n");
  16.         return;
  17.     }
  18.     node->fd = fd;
  19.     node->next = NULL;
  20.     if (queue->tail == NULL) {
  21.         queue->head = queue->tail = node;
  22.         return;
  23.     }
  24.     queue->tail->next = node;
  25.     queue->tail = node;
  26. }

  27. int dequeue(queue_t *queue)
  28. {
  29.     assert(queue);
  30.     if (queue->tail == NULL && queue->head == NULL) {
  31.         //printf("dequeue() queue is empty!\n");
  32.         return -1;
  33.     }
  34.     qnode_t *tmp = NULL;
  35.     int ret = -1;
  36.     tmp = queue->head;
  37.     ret = tmp->fd;
  38.     queue->head = tmp->next;
  39.     //如果出对到队尾了,需要将队尾更新为空,以便于后续再次执行入对操作
  40.     if (queue->tail == tmp)
  41.         queue->tail = queue->tail->next;
  42.     free(tmp);
  43.     return ret;
  44. }

  45. void traverse(queue_t *q)
  46. {
  47.     unsigned long pid = pthread_self();
  48.     if (q->head == NULL) {
  49.         printf("traverse() {%d} queue is empty!\n",pid);
  50.         return;
  51.     }
  52.     
  53.     qnode_t *pos = NULL;
  54.     int i = 0;
  55.     for (pos = q->head;pos != NULL; pos = pos->next,i++) {
  56.         printf("traverse{%lu} pos[%d]=%d\n",pid,i,pos->fd);
  57.     }
  58. }
验证程序
[root@TEST_190 comm_queue]# cat main.c

  1. #include "queue.h"

  2. int count = 10000;
  3. pthread_mutex_t m;
  4. queue_t queue = {NULL, NULL};
  5. void *writer_thread(void *param);
  6. void *reader_thread(void *param);

  7. int main(void)
  8. {
  9.     struct timeval start,end;
  10.     gettimeofday(&start, NULL);
  11.     pthread_t writer,reader;
  12.     pthread_mutex_init(&m, NULL);
  13.     pthread_create(&writer, NULL, writer_thread, NULL);
  14.     pthread_create(&reader, NULL, reader_thread, NULL);

  15.     pthread_join(writer, NULL);
  16.     pthread_join(reader, NULL);
  17.     gettimeofday(&end, NULL);
  18.     double elasp = (end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec);
  19.     printf("pthread id = %lu, elasp = %f\n", pthread_self(), elasp);
  20.     //traverse(&queue);
  21.     return 0;
  22. }

  23. void *writer_thread(void *param)
  24. {
  25.     int i;
  26.     for (i = 0; i < count; i++ ) {
  27.         pthread_mutex_lock(&m);
  28.         enqueue(&queue,i);
  29.         printf("enqueue [%d]\n",i);
  30.         pthread_mutex_unlock(&m);
  31.     }
  32.     //traverse(&queue);
  33. }

  34. void *reader_thread(void *param)
  35. {
  36.     int ret=0,i;
  37.     //模拟无限出队的情况,暂时执行次数为 100*count
  38.     for(i=0;i<100*count;i++) {
  39.         pthread_mutex_lock(&m);
  40.         ret = dequeue(&queue);
  41.         if (ret == -1) {
  42.             printf(".");
  43.         } else {
  44.             printf("dequeue ret = %d\n",ret);
  45.         }
  46.         
  47.         pthread_mutex_unlock(&m);
  48.     }
  49.     //traverse(&queue);
  50. }

编译和确认,需要查看log确认,队列为空时的出队操作,会打出“.”:

  1. gcc queue.c main.c -o q1 -g -lpthread
  2. ./q1 | tee log



阅读(226) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~