zl程序教程

您现在的位置是:首页 >  前端

当前栏目

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

循环队列队列 为什么 具有 随想录
2023-09-27 14:27:11 时间

【声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


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


    同样而言,循环队列具有很强的并行性,如果服务的数据比较少,那么完全可以利用两个线程进行数据的保存和处理工作。只要注意在编写队列的时候不要引入公共参数,那么几乎不会有任何的并行烦恼。这其中的原因就在于,循环队列没有公共变量,所以不存在对公共变量的修改问题。队列是否为空或者是否为满,完全可以由队列的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;
}