首页 > 其他分享 >随想录(为什么循环队列具有先天的并行性)

随想录(为什么循环队列具有先天的并行性)

时间:2022-11-23 11:34:09浏览次数:29  
标签:QUEUE end 队列 随想录 并行性 queue int NULL data




    循环队列是很多人喜欢用的一种数据结构。本着先来先服务的特性,循环队列是一种十分简单、健壮的数据结构。不像链表、二叉树,如果使用不慎,就会造成很大的麻烦,但是在循环队列上面则没有这个烦恼。


    同样而言,循环队列具有很强的并行性,如果服务的数据比较少,那么完全可以利用两个线程进行数据的保存和处理工作。只要注意在编写队列的时候不要引入公共参数,那么几乎不会有任何的并行烦恼。这其中的原因就在于,循环队列没有公共变量,所以不存在对公共变量的修改问题。队列是否为空或者是否为满,完全可以由队列的start和end这两个参数决定,而这两个参数的修改是分开来的,不可能在一个线程上面解决,这就是队列并行的本质原因。


    同学们可以自己编写一个简单的双线程代码,验证自己的想法,同时可以不断加深自己对多线程代码的分析和理解能力。下面就是一段在linux上编写的队列处理代码,欢迎大家多提宝贵意见。编译的方法十分简单,即gcc queue.c -g -o queue -lpthread,这里加上-g主要是为了调试使用。


#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <pthread.h>

struct QUEUE
{
int* buffer;
int count;
int start;
int end;
};

#define STATUS int
#define TRUE 1
#define FALSE 0

struct QUEUE* alloc_queue(int count)
{
struct QUEUE* p_queue;

if(0 == count)
{
goto error1;
}

p_queue = (struct QUEUE*)malloc(sizeof(struct QUEUE));
if(NULL == p_queue)
{
goto error1;
}
memset(p_queue, 0, sizeof(struct QUEUE));
p_queue->count = count;

p_queue->buffer = (int*)malloc(sizeof(int)* count);
if(NULL == p_queue->buffer)
{
goto error2;
}

memset(p_queue->buffer, 0, sizeof(int) * count);
return p_queue;

error2:
free(p_queue);

error1:
return NULL;
}


STATUS add_data_into_queue(struct QUEUE* p_queue, int data)
{
if(NULL == p_queue)
{
return FALSE;
}

if(p_queue->end == (p_queue->start + 1) % p_queue->count)
{
return FALSE;
}

p_queue->buffer[p_queue->start] = data;
p_queue->start = (p_queue->start + 1) % p_queue->count;
return TRUE;
}


STATUS get_data_from_queue(struct QUEUE* p_queue, int* p_data)
{
if(NULL == p_queue || NULL == p_data)
{
return FALSE;
}

if(p_queue->start == p_queue->end)
{
return FALSE;
}

p_data[0] = p_queue->buffer[p_queue->end];
p_queue->end = (p_queue->end + 1) % p_queue->count;
return TRUE;
}


static void* set_func(void* args)
{
int index = 1;

if(NULL == args)
{
goto end;
}

while(1)
{
while(FALSE == add_data_into_queue((struct QUEUE*)args, index));
printf("set data %d\n", index ++);
sleep(1);
}

end:
return NULL;
}


static void* get_func(void* args)
{
int data;

if(NULL == args)
{
goto end;
}

while(1)
{
while(FALSE == get_data_from_queue((struct QUEUE*)args, &data));
printf("find data %d\n", data);
sleep(3);
}

end:
return NULL;
}


int main(int argc, char* argv[])
{
pthread_t pid1, pid2;
struct QUEUE* p_queue;

p_queue = alloc_queue(10);
if(NULL == p_queue)
{
goto end;
}

if(pthread_create(&pid1, NULL, set_func, p_queue))
{
goto end;
}

if(pthread_create(&pid2, NULL, get_func, p_queue))
{
goto end;
}

while(1)
{
sleep(0);
}

end:
return 1;
}




标签:QUEUE,end,队列,随想录,并行性,queue,int,NULL,data
From: https://blog.51cto.com/feixiaoxing/5880709

相关文章

  • 随想录(linux下的pv操作)
         关于pv操作部分的内容,其实算不上什么新的东西。但是它对于我们理解信号量、消息处理部分的工作还是有很大帮助的。之前我们给出了一个win32的处理方案,但是实现的......
  • 随想录(写给那些学校不是985、211的同学们)
       每年的6、7月份都是一年一度的毕业季。按照某些新闻机构的统计数字来说,现在每一年毕业的人数达到了600万之多。然而随着社会经济的放缓、贫富差距的拉开,找工作变得越......
  • 随想录(用memmove函数代替strncpy函数)
        有过C语言编程的朋友应该都有过指针越界的困扰。不管越界的地方是全局地址、还是局部地址,查起来都是非常麻烦,原因大多时候都来自于自己对char数组类型的误用。很多......
  • 随想录(编写简单资源管理代码)
      不管编写什么软件,我们都会涉及到模块的编写。说是模块,其实就是管理一片资源,这些资源的概念很广,可以是内存、锁、socket、字符串、文件、空间大小等等。所以不管是什么......
  • 随想录(设计软件模块的接口)
       开发软件是一件复杂而且辛苦的工作,不同的模块之间的逻辑需要考虑,应用层与底层的关系也需要考虑。模块之间的关系处理不好,就会给软件的编写质量带来影响。当然不管软......
  • 随想录(矩阵计算的几种方法)
    【声明:版权所有,欢迎转载,请勿用于商业用途。】   要进行图像处理,矩阵运算是少不了的。不管是加减乘除,还是旋转、求逆、矩阵分解,都需要lib来好好支持。下面,主要就说一......
  • 随想录(机器学习的生产应用)
    【声明:版权所有,欢迎转载,请勿用于商业用途。     从范围上讲,人工智能>机器学习>模式识别。最近机器学习愈演愈烈,特别是深度学习的发展,极大的推动了机器学习的应......
  • 随想录(嵌入式工程师的出路)
    【声明:版权所有,欢迎转载,请勿用于商业用途。  嵌入式工程师分布在各行各业上面。这其中包括了消费电子、工业电子、汽车电子和军用电子等等。从功能上面看,嵌入式本身包......
  • 随想录(对比着c学java)
    【声明:版权所有,欢迎转载,请勿用于商业用途。  对于java,有两种论调。一种是鄙视,认为java是个人都能学,完全体现不出程序员的水平。还有一种,就是拔高java,认为java无所不能,j......
  • 随想录(被高估的busybox)
    【声明:版权所有,欢迎转载,请勿用于商业用途。  传统的嵌入式系统都是uboot+kernel+rootfs。其中最简单的rootfs就是ramfs+busybox+/dev+/etc+/lib。至于etc目录中的initt......