嵌入式学习第三十天--队列
队列:
队列是只允许在一段进行插入,而在另一端进行删除操作的线性表。
允许插入的称谓队尾,允许删除的一端队头。
顺序队列。
循环队列,
常用操作,入队,出队。
先进先出,FIFO
seqque.h
#ifndef __SEQQUE_H__
#define __SEQQUE_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <errno.h>
typedef int DATATYPE;
typedef struct queue {
DATATYPE *array;
int tlen;
int head;
int tail;
}SeqQueue;
SeqQueue *CreateSeqQueue(int len);
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data);
int QuitSeqQueue(SeqQueue *queue);
int IsEmptySeqQueue(SeqQueue *queue);
int IsFullSeqQueue(SeqQueue *queue);
DATATYPE* GetHeadSeqQue(SeqQueue *queue);
int DestroySeqQueue(SeqQueue *queue);
#endif
seqque.c
#include "./seqque.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
SeqQueue *CreateSeqQueue(int len)
{
SeqQueue* sq = malloc(sizeof(SeqQueue));
if(NULL == sq)
{
perror("CreateSeqQueue malloc error\n");
return NULL;
}
sq->array = malloc(sizeof(DATATYPE)*len);
if(NULL == sq->array)
{
perror("CreateSeqQueue malloc2 error\n");
return NULL;
}
sq->head = 0 ;
sq->tail = 0 ;
sq->tlen = len;
return sq;
}
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data)
{
if(NULL == queue || NULL == data)
{
fprintf(stderr,"EnterSeqQueue paramter error\n");
return 1;
}
if(IsFullSeqQueue(queue))
{
fprintf(stderr,"queue full\n");
return 1;
}
memcpy(&queue->array[queue->tail],data,sizeof(DATATYPE));
queue->tail = (queue->tail+1) % queue->tlen;
return 0;
}
int QuitSeqQueue(SeqQueue *queue)
{
if(NULL == queue )
{
fprintf(stderr,"QuitSeqQueue paramter error\n");
return 1;
}
if(IsEmptySeqQueue(queue))
{
fprintf(stderr,"queue empty\n");
return 1;
}
queue->head = (queue->head +1) %queue->tlen;
return 0;
}
int IsEmptySeqQueue(SeqQueue *queue)
{
return queue->head == queue->tail;
}
int IsFullSeqQueue(SeqQueue *queue)
{
return (queue->tail +1 )%queue->tlen == queue->head;
}
DATATYPE* GetHeadSeqQue(SeqQueue *queue)
{
if(NULL == queue )
{
fprintf(stderr,"GetHeadSeqQue paramter error\n");
return NULL;
}
if(IsEmptySeqQueue(queue))
{
fprintf(stderr,"queue empty\n");
return NULL;
}
return &queue->array[queue->head];
}
int DestroySeqQueue(SeqQueue *queue)
{
if(NULL == queue )
{
fprintf(stderr,"DestroySeqQueue paramter error\n");
return 1;
}
free(queue->array);
free(queue);
return 0;
}
int GetSizeSeqQueue(SeqQueue *queue)
{
return (queue->tail - queue->head +queue->tlen )%queue->tlen;
}
main.c
#include <stdio.h>
#include "./seqque.h"
int main(int argc, char **argv)
{
SeqQueue* sq = CreateSeqQueue(10);
for(int i = 0 ;i<10;i++)
{
EnterSeqQueue(sq, &i);
}
while(!IsEmptySeqQueue(sq))
{
DATATYPE* temp =GetHeadSeqQue(sq);
printf("%d\n",*temp);
QuitSeqQueue(sq);
}
DestroySeqQueue(sq);
//system("pause");
return 0;
}
队列练习:创建三个线程,对应三个任务,在主线程中输出要进行的操作,打印相应的输出。
seqque.h
#ifndef __SEQQUE_H__
#define __SEQQUE_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <errno.h>
typedef struct
{
char task_name[50];
int task_time;
} DATATYPE;
typedef struct queue
{
DATATYPE *array;
int tlen;
int head;
int tail;
} SeqQueue;
SeqQueue *CreateSeqQueue(int len);
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data);
int QuitSeqQueue(SeqQueue *queue);
int IsEmptySeqQueue(SeqQueue *queue);
int IsFullSeqQueue(SeqQueue *queue);
DATATYPE *GetHeadSeqQue(SeqQueue *queue);
int DestroySeqQueue(SeqQueue *queue);
int GetSizeSeqQueue(SeqQueue *queue);
#endif
seqque.c
#include "./seqque.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
SeqQueue *CreateSeqQueue(int len)
{
SeqQueue *sq = malloc(sizeof(SeqQueue));
if (NULL == sq)
{
perror("CreateSeqQueue malloc error\n");
return NULL;
}
sq->array = malloc(sizeof(DATATYPE) * len);
if (NULL == sq->array)
{
perror("CreateSeqQueue malloc2 error\n");
return NULL;
}
sq->head = 0;
sq->tail = 0;
sq->tlen = len;
return sq;
}
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data)
{
if (NULL == queue || NULL == data)
{
fprintf(stderr, "EnterSeqQueue paramter error\n");
return 1;
}
if (IsFullSeqQueue(queue))
{
fprintf(stderr, "queue full\n");
return 1;
}
memcpy(&queue->array[queue->tail], data, sizeof(DATATYPE));
queue->tail = (queue->tail + 1) % queue->tlen;
return 0;
}
int QuitSeqQueue(SeqQueue *queue)
{
if (NULL == queue)
{
fprintf(stderr, "QuitSeqQueue paramter error\n");
return 1;
}
if (IsEmptySeqQueue(queue))
{
fprintf(stderr, "queue empty\n");
return 1;
}
queue->head = (queue->head + 1) % queue->tlen;
return 0;
}
int IsEmptySeqQueue(SeqQueue *queue)
{
return queue->head == queue->tail;
}
int IsFullSeqQueue(SeqQueue *queue)
{
return (queue->tail + 1) % queue->tlen == queue->head;
}
DATATYPE *GetHeadSeqQue(SeqQueue *queue)
{
if (NULL == queue)
{
fprintf(stderr, "GetHeadSeqQue paramter error\n");
return NULL;
}
if (IsEmptySeqQueue(queue))
{
fprintf(stderr, "queue empty\n");
return NULL;
}
return &queue->array[queue->head];
}
int DestroySeqQueue(SeqQueue *queue)
{
if (NULL == queue)
{
fprintf(stderr, "DestroySeqQueue paramter error\n");
return 1;
}
free(queue->array);
free(queue);
return 0;
}
int GetSizeSeqQueue(SeqQueue *queue)
{
return (queue->tail - queue->head + queue->tlen) % queue->tlen;
}
main.c
#include <stdio.h>
#include "./seqque.h"
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>
sem_t sem_task;
void *th(void *arg)
{
SeqQueue *sq = (SeqQueue *)arg;
DATATYPE data;
while (1)
{
sem_wait(&sem_task); // 阻塞等待
DATATYPE *tmp = GetHeadSeqQue(sq);
memcpy(&data, tmp, sizeof(DATATYPE));
if (0 == strcmp(tmp->task_name, "over"))
{
break;
}
QuitSeqQueue(sq);
while (data.task_time--)
{
printf("i'm %s\n", data.task_name);
sleep(1);
}
}
return NULL;
}
int main(int argc, char **argv)
{
DATATYPE task_data[] = {
{"washing", 3},
{"cooking", 5},
{"homeworking ", 2},
{"over", 5},
};
sem_init(&sem_task, 0, 0);
SeqQueue *sq = CreateSeqQueue(10);
pthread_t tid;
pthread_create(&tid, NULL, th, sq);
for (int i = 0; i < 4; i++)
{
printf("%d %s\n", i, task_data[i].task_name);
}
DATATYPE data;
int run_flag = 1;
while (run_flag)
{
bzero(&data, sizeof(data));
int choose = -1;
char buf[5] = {0};
fgets(buf, sizeof(buf), stdin); // 1\n
choose = atoi(buf);
switch (choose)
{
case 0:
memcpy(&data, &task_data[0], sizeof(DATATYPE));
EnterSeqQueue(sq, &data);
sem_post(&sem_task);
break;
case 1:
memcpy(&data, &task_data[1], sizeof(DATATYPE));
EnterSeqQueue(sq, &data);
sem_post(&sem_task);
break;
case 2:
memcpy(&data, &task_data[2], sizeof(DATATYPE));
EnterSeqQueue(sq, &data);
sem_post(&sem_task);
break;
case 3:
memcpy(&data, &task_data[3], sizeof(DATATYPE));
EnterSeqQueue(sq, &data);
sem_post(&sem_task);
run_flag = 0;
break;
default:
break;
}
}
pthread_join(tid, NULL);
sem_destroy(&sem_task);
DestroySeqQueue(sq);
// system("pause");
return 0;
}
演示结果如下:
练习:找出指定目录下出现#define的文件,打印当前文件的路径。
seqque.h
#ifndef __SEQQUE_H__
#define __SEQQUE_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <errno.h>
typedef struct
{
char path[512];
} DATATYPE;
typedef struct queue
{
DATATYPE *array;
int tlen;
int head;
int tail;
} SeqQueue;
SeqQueue *CreateSeqQueue(int len);
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data);
int QuitSeqQueue(SeqQueue *queue);
int IsEmptySeqQueue(SeqQueue *queue);
int IsFullSeqQueue(SeqQueue *queue);
DATATYPE *GetHeadSeqQue(SeqQueue *queue);
int DestroySeqQueue(SeqQueue *queue);
int GetSizeSeqQueue(SeqQueue *queue);
#endif
seqque.c
#include "./seqque.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
SeqQueue *CreateSeqQueue(int len)
{
SeqQueue *sq = malloc(sizeof(SeqQueue));
if (NULL == sq)
{
perror("CreateSeqQueue malloc error\n");
return NULL;
}
sq->array = malloc(sizeof(DATATYPE) * len);
if (NULL == sq->array)
{
perror("CreateSeqQueue malloc2 error\n");
return NULL;
}
sq->head = 0;
sq->tail = 0;
sq->tlen = len;
return sq;
}
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data)
{
if (NULL == queue || NULL == data)
{
fprintf(stderr, "EnterSeqQueue paramter error\n");
return 1;
}
if (IsFullSeqQueue(queue))
{
fprintf(stderr, "queue full\n");
return 1;
}
memcpy(&queue->array[queue->tail], data, sizeof(DATATYPE));
queue->tail = (queue->tail + 1) % queue->tlen;
return 0;
}
int QuitSeqQueue(SeqQueue *queue)
{
if (NULL == queue)
{
fprintf(stderr, "QuitSeqQueue paramter error\n");
return 1;
}
if (IsEmptySeqQueue(queue))
{
fprintf(stderr, "queue empty\n");
return 1;
}
queue->head = (queue->head + 1) % queue->tlen;
return 0;
}
int IsEmptySeqQueue(SeqQueue *queue)
{
return queue->head == queue->tail;
}
int IsFullSeqQueue(SeqQueue *queue)
{
return (queue->tail + 1) % queue->tlen == queue->head;
}
DATATYPE *GetHeadSeqQue(SeqQueue *queue)
{
if (NULL == queue)
{
fprintf(stderr, "GetHeadSeqQue paramter error\n");
return NULL;
}
if (IsEmptySeqQueue(queue))
{
fprintf(stderr, "queue empty\n");
return NULL;
}
return &queue->array[queue->head];
}
int DestroySeqQueue(SeqQueue *queue)
{
if (NULL == queue)
{
fprintf(stderr, "DestroySeqQueue paramter error\n");
return 1;
}
free(queue->array);
free(queue);
return 0;
}
int GetSizeSeqQueue(SeqQueue *queue)
{
return (queue->tail - queue->head + queue->tlen) % queue->tlen;
}
main.c
#include <stdio.h>
#include "./seqque.h"
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#define PATH "/home/linux/20241230cd"
pthread_t main_th;
sem_t sem_task;
int do_check(char *filename, FILE *dstfp)
{
// /home/linux/1/2/3/4.h .h
if (strlen(filename) < 3 && 0 != strcmp(&filename[strlen(filename) - 2], ".h"))
{
return 1;
}
int num = 1;
FILE *fp = fopen(filename, "r");
if (NULL == fp)
{
perror("do_check fopen\n");
return 1;
}
while (1)
{
char buf[512] = {0};
if (NULL == fgets(buf, sizeof(buf), fp))
{
break;
}
if (strstr(buf, "#define"))
{
fprintf(dstfp, "%s %d %s", filename, num, buf);
}
num++;
}
fclose(fp);
}
int do_ls(char *path, SeqQueue *sq, FILE *dstfp)
{
DIR *dir = opendir(path); // home/linux
if (NULL == dir)
{
perror("do_ls opendir error\n");
return 1;
}
DATATYPE data;
char newpath[512] = {0};
while (1)
{
bzero(&data, sizeof(data));
bzero(newpath, sizeof(path));
struct dirent *info = readdir(dir);
if (NULL == info)
{
break;
}
sprintf(newpath, "%s/%s", path, info->d_name);
printf("processing : %s \n", newpath);
if (DT_DIR == info->d_type)
{
if (0 == strcmp(info->d_name, ".") || 0 == strcmp(info->d_name, ".."))
{
continue;
}
if (main_th == pthread_self()) // main
{
strcpy(data.path, newpath); // home/linux/1/
EnterSeqQueue(sq, &data);
sem_post(&sem_task);
}
else
{
do_ls(newpath, sq, dstfp);
}
}
else // home/linux/1
{
if (DT_FIFO == info->d_type || DT_LNK == info->d_type)
{
continue;
}
do_check(newpath, dstfp);
}
}
closedir(dir);
}
typedef struct
{
SeqQueue *sq;
FILE *fp;
} TH_ARG;
void *th(void *arg)
{
TH_ARG *tmp = (TH_ARG *)arg;
while (1)
{
char path[512] = {0};
sem_wait(&sem_task);
DATATYPE *ret = GetHeadSeqQue(tmp->sq);
strcpy(path, ret->path);
QuitSeqQueue(tmp->sq);
if (0 == strcmp(path, "over"))
{
break;
}
do_ls(path, tmp->sq, tmp->fp);
}
return NULL;
}
int main(int argc, char **argv)
{
SeqQueue *sq = CreateSeqQueue(10000);
main_th = pthread_self();
sem_init(&sem_task, 0, 0);
pthread_t tid1, tid2, tid3;
FILE *fp = fopen("log", "w");
if (NULL == fp)
{
perror("main fopen\n");
return 1;
}
TH_ARG arg;
arg.fp = fp;
arg.sq = sq;
pthread_create(&tid1, NULL, th, &arg);
pthread_create(&tid2, NULL, th, &arg);
pthread_create(&tid3, NULL, th, &arg);
do_ls(PATH, sq, fp);
for (int i = 0; i < 3; i++)
{
DATATYPE data = {0};
strcpy(data.path, "over");
EnterSeqQueue(sq, &data);
sem_post(&sem_task);
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
DestroySeqQueue(sq);
fclose(fp);
sem_destroy(&sem_task);
return 0;
}
演示结果:
下面总结链队的结构
linkque.h
#ifndef __LINK_QUE_H__
#define __LINK_QUE_H__
typedef struct person
{
char name[32];
char sex;
int age;
int score;
} DATATYPE;
typedef struct quenode
{
DATATYPE data;
struct quenode *next;
} LinkQueNode;
typedef struct
{
LinkQueNode *head;
LinkQueNode *tail;
int clen;
} LinkQue;
LinkQue *CreateLinkQue();
int EnterLinkQue(LinkQue *lq, DATATYPE *data);
int QuitLinkQue(LinkQue *lq);
DATATYPE *GetHeadLinkQue(LinkQue *lq);
int IsEmptyLinkQue(LinkQue *lq);
int GetSizeLinkQue(LinkQue *lq);
int DestroyLinkQue(LinkQue *lq);
#endif
linkque.c
#include "./linkque.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
LinkQue *CreateLinkQue()
{
LinkQue *lq = malloc(sizeof(LinkQue));
if (NULL == lq)
{
perror("CreateLinkQue malloc error\n");
return NULL;
}
lq->head = NULL;
lq->tail = NULL;
lq->clen = 0;
return lq;
}
int EnterLinkQue(LinkQue *lq, DATATYPE *data)
{
LinkQueNode *newnode = malloc(sizeof(LinkQueNode));
if (NULL == newnode)
{
perror("EnterLinkQue malloc error\n");
return 1;
}
memcpy(&newnode->data, data, sizeof(DATATYPE));
newnode->next = NULL;
if (IsEmptyLinkQue(lq))
{
lq->head = newnode;
lq->tail = newnode;
}
else
{
lq->tail->next = newnode;
lq->tail = newnode;
}
lq->clen++;
return 0;
}
int QuitLinkQue(LinkQue *lq)
{
if (NULL == lq)
{
fprintf(stderr, "QuitLinkQue paramter error\n");
return 1;
}
LinkQueNode *tmp = lq->head;
lq->head = lq->head->next;
free(tmp);
if (NULL == lq->head) // del last one
{
lq->tail = NULL;
}
lq->clen--;
return 0;
}
DATATYPE *GetHeadLinkQue(LinkQue *lq)
{
if (NULL == lq)
{
fprintf(stderr, "GetHeadLinkQue paramter error\n");
return NULL;
}
return &lq->head->data;
}
int IsEmptyLinkQue(LinkQue *lq)
{
return 0 == lq->clen;
}
int GetSizeLinkQue(LinkQue *lq)
{
return lq->clen;
}
int DestroyLinkQue(LinkQue *lq)
{
if (NULL == lq)
{
fprintf(stderr, "DestroyLinkQue paramter error\n");
return 1;
}
int len = GetSizeLinkQue(lq);
for (int i = 0; i < len; i++)
{
QuitLinkQue(lq);
}
free(lq);
return 0;
}
main.c
#include "./linkque.h"
#include <stdio.h>
int main(int argc, char **argv)
{
DATATYPE data[] = {
{"zhangsan", 'm', 20, 80},
{"lisi", 'f', 22, 86},
{"wangmazi", 'f', 22, 67},
{"guanerge", 'm', 40, 88},
{"liubei", 'm', 42, 90},
};
LinkQue *lq = CreateLinkQue();
for (int i = 0; i < 5; i++)
{
EnterLinkQue(lq, &data[i]);
}
int size = GetSizeLinkQue(lq);
for (int i = 0; i < size; i++)
{
DATATYPE *dat = GetHeadLinkQue(lq);
printf("name:%s score:%d\n", dat->name, dat->score);
QuitLinkQue(lq);
}
DestroyLinkQue(lq);
lq = NULL;
// system("pause");
return 0;
}
运行结果: