linux——20线程池

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、线程池模型

线程池模型比起多线程的优势,减少了线程创建和 线程回收的时间。
线程池的应用:
(1)程序需要设计多线程
(2)频繁的开辟线程和关闭线程
模式大概分为三个部分:
主控线程————工作线程————任务队列
模型图为:
在这里插入图片描述

二、使用步骤

1.线程池描述

总共设置四个线程,一个主线程用于控制子线程,三个子线程用于执行任务。
完成两者之间的沟通时需要两个技术,信号量和互斥锁。
主线程的工作:将需要的任务进行入队操作(上互斥锁),并申请一个信号量(信号量的初始值为1)。
子线程的工作:阻塞等待释放信号量,出队(上互斥锁)拿到所需的任务完成工作。

2.源码

代码如下(示例):

heah.h

#ifndef __HEAD_H__
#define __HEAD_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
typedef struct
{
	char path[256];
	FILE* fp;
}DATATYPE;

typedef struct node {
	DATATYPE data;
	struct node *next;
}QueueNode;

typedef struct queue {
	QueueNode *head;
	QueueNode *tail;
	int clen;
}LinkQueue;
extern int DestroyLinkQueue(LinkQueue *queue);
extern int QuitLinkQueue(LinkQueue *queue,DATATYPE *data);
extern int EnterLinkQueue(LinkQueue *queue, DATATYPE *data);
extern int IsFullLinkQueue(LinkQueue *queue);
extern int IsEmptyLinkQueue(LinkQueue *queue);
extern LinkQueue *CreateLinkQueue();
extern int ClearLinkQueue(LinkQueue *queue);
extern int GetHeadLinkQueue(LinkQueue *queue,DATATYPE*data);
extern int GetSizeLinkQueue(LinkQueue *queue);

#endif

fun.c

#include "head.h"

LinkQueue *CreateLinkQueue()
{
	LinkQueue* temp = malloc(sizeof(LinkQueue));
	if(NULL == temp)
	{
		perror("CreateLinkQueue malloc");
		return NULL;
	}
	temp->head = NULL;
	temp->tail =NULL;
	temp->clen = 0 ;
	return temp;
}

int IsEmptyLinkQueue(LinkQueue *q)
{
	return 0 == q->clen ;
}

int EnterLinkQueue(LinkQueue *q, DATATYPE *data)
{
	QueueNode* newnode = malloc(sizeof(QueueNode));
	if(NULL == newnode)
	{
		perror("EnterLinkQueue malloc");
		return 1;
	}
	memcpy(&newnode->data,data,sizeof(*data));
	newnode->next= NULL;
	if(IsEmptyLinkQueue(q))
	{
		q->head = newnode;
		q->tail = newnode;
	}
	else
	{
		q->tail->next = newnode;
		q->tail = newnode;
	}
	q->clen++;
	return 0;
}
int QuitLinkQueue(LinkQueue *queue,DATATYPE *data)
{
	if(IsEmptyLinkQueue(queue))
	{
		printf("queue is empty\n");
		return 1;
	}
	memcpy(data,&queue->head->data,sizeof(*data));
	QueueNode* temp = queue->head;
	queue->head = queue->head->next;
	if(NULL == queue->head)
	{
		queue->tail = NULL;
	}
	free(temp);
	queue->clen--;
	return 0;
}

int ClearLinkQueue(LinkQueue *queue)
{
	QueueNode* temp = queue->head;
	while(temp)
	{
		queue->head = queue->head->next;
		free(temp);
		temp = queue->head;
	}
	queue->head =NULL;
	queue->tail =NULL;
	queue->clen = 0;
	return 0;
}
int DestroyLinkQueue(LinkQueue *queue)
{
	ClearLinkQueue(queue);
	free(queue);
	return 0;
}
int GetHeadLinkQueue(LinkQueue *queue,DATATYPE*data)
{
	if(IsEmptyLinkQueue(queue))
	{
		printf("queue is empty\n");
		return 1;
	}
	memcpy(data,&queue->head->data,sizeof(*data));
	return 0;
}

int GetSizeLinkQueue(LinkQueue *queue)
{
	return queue->clen;
}


main.c

#include "head.h"
sem_t sem_task;
pthread_mutex_t lock;
int do_write(char* file,FILE* fp)
{
	FILE* srcfp = fopen(file,"r");
	if(NULL == srcfp)
	{
		perror("do_write, fopen");
		return 1;
	}
	char buf[512]={0};
	int num = 0;
	while(1)
	{
		if(NULL==fgets(buf,sizeof(buf),srcfp))
		{
			break;
		}

		num++;
		if(strstr(buf,"#define"))
		{
			fprintf(fp,"%s\t %d %s",file,num,buf);
			fflush(fp);
		}
	}
	fclose(srcfp);
	return 0;
}
int do_process(char* path,LinkQueue* q ,FILE* fp,int flag) // flag 0 main, 1 subthread
{
	DIR* dir = opendir(path);
	DATATYPE data;
	if(NULL == dir)
	{
		perror("opendir");
		return 1;
	}
	struct dirent* info;
	while(1)
	{
		info = readdir(dir);
		if(NULL == info)
		{
			break;
		}
		if(DT_DIR == info->d_type)
		{

			if(0 == strcmp(info->d_name,".") || 0 == strcmp(info->d_name,".."))
			{
				continue;
			}

			bzero(&data,sizeof(data));
			sprintf(data.path,"%s/%s",path,info->d_name);
			if(0 == flag)//main
			{
				data.fp = fp;
				pthread_mutex_lock(&lock);
				EnterLinkQueue(q,&data);
				pthread_mutex_unlock(&lock);
				printf("main, %lu enter %s\n",pthread_self(),data.path);
				sem_post(&sem_task);
			}
			else 
			{
				do_process(data.path,q,fp,1);
			}
		}
		else  
		{
			if(strlen(info->d_name)<3)
			{
				continue;
			}
			if(0 == strcmp(&info->d_name[strlen(info->d_name)-2],".c")
					||0 == strcmp(&info->d_name[strlen(info->d_name)-2],".h"))

			{
				sprintf(data.path,"%s/%s",path,info->d_name);
				do_write(data.path,fp);
			}


		}
	}
	closedir(dir);
	return 0;
}
void * th(void* arg)
{
	while(1)
	{
		sem_wait(&sem_task);
		LinkQueue* q = ( LinkQueue*)arg;
		DATATYPE data;
		pthread_mutex_lock(&lock);
		QuitLinkQueue(q,&data);
		pthread_mutex_unlock(&lock);
		if(0 == strcmp(data.path,"_over_"))
		{
			break;
		}
		printf("sub, %lu quit %s\n",pthread_self(),data.path);
		do_process(data.path,q,data.fp,1);
	}
	return NULL;
}
int main(void)
{

	pthread_t tid1,tid2,tid3;
	sem_init(&sem_task,0,0);
	pthread_mutex_init(&lock,NULL);
	LinkQueue* q = CreateLinkQueue();
	pthread_create(&tid1,NULL,th,q);
	pthread_create(&tid2,NULL,th,q);
	pthread_create(&tid3,NULL,th,q);
	FILE* fp = fopen("log.txt","w");
	if(NULL == fp)
	{
		perror("fopen");
		pthread_cancel(tid1);
		pthread_cancel(tid2);
		pthread_cancel(tid3);
		DestroyLinkQueue(q);
		exit(1);
	}
	do_process("/home/linux/01pute_c",q,fp,0);
	printf("main thread over\n");
	DATATYPE data;
	int i = 0 ;
	for(i = 0 ;i<3;i++)
	{
		strcpy(data.path,"_over_");
		pthread_mutex_lock(&lock);
		EnterLinkQueue(q,&data);
		pthread_mutex_unlock(&lock);
		sem_post(&sem_task);
	}
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_join(tid3,NULL);
	DestroyLinkQueue(q);
	sem_destroy(&sem_task);
	pthread_mutex_destroy(&lock);
	fclose(fp);
	printf("Hello World!\n");
	return 0;
}

Makefile

OBJ=all
SRC=main.o fun.o 
CC=gcc
LFLAG=-g -lpthread
$(OBJ):$(SRC)
	$(CC) $^ -o $@ $(LFLAG)
%.o:%.c
	$(CC) -c $< -o $@

clean:
	rm $(OBJ)
disclean:
	rm $(OBJ) *.o
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值