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

文章目录

  • 前言
  • 一、线程池模型
  • 二、使用步骤
    • 1.线程池描述
    • 2.源码

前言

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


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

一、线程池模型

线程池模型比起多线程的优势,减少了线程创建和 线程回收的时间。
线程池的应用:
(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

linux——20线程池相关推荐

  1. linux下线程池实现

    linux下线程池实现 转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为 ...

  2. linux动态线程池--原理,这儿的代码不完整

    本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池中线程的数量.文章的最后,我们 ...

  3. Linux C++线程池

    这是对pthread线程的一个简单应用 1.      实现了线程池的概念,线程可以重复使用. 2.      对信号量,互斥锁等进行封装,业务处理函数中只需写和业务相关的代码. 3.      移植 ...

  4. linux c++线程池的实现

    http://blog.csdn.net/zhoubl668/article/details/8927090?t=1473221020107 线程池的原理大家都知道,直接上代码了^_^ Thread. ...

  5. Linux C++线程池实例

    http://www.cnblogs.com/danxi/p/6636095.html 想做一个多线程服务器测试程序,因此参考了github的一些实例,然后自己动手写了类似的代码来加深理解. 目前了解 ...

  6. linux 下线程池

    基本想法是这样的:       1.预创建的线程通过mutex休眠在线程池中.这样,通过unlock该mutex就可以唤醒该线程了:       2.出于简单性的目标,一个线程池内的所有线程的属性都是 ...

  7. 简单Linux C线程池

    大多数的网络服务器,包括Web服务器都具有一个特点,就是单位时间内必须处理数目巨大的连接请求,但是处理时间却是比较短的.在传统的多线程服务器模型中是这样实现的:一旦有个请求到达,就创建一个新的线程,由 ...

  8. linux nginx线程池,nginx使用线程池提升9倍性能

    众所周知nginx使用异步,事件驱动方法处理连接.这意味着nginx使用一个worker进程处理多个连接和请求,而不是每一个请求有一个专门的进程或着线程处理(像传统架构的服务器那样,例如apache) ...

  9. linux posix 线程池_linux多线程--POSIX Threads Programming

    linux多线程自己从接触很久也有不少实践,但总是觉得理解不够深刻,不够系统.借这篇文章试着再次系统学习一下linux多线程编程,理解编程的concept,细致看一下POSIX pthread API ...

  10. 谈一谈linux下线程池

    什么是线程池: 首先,顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线 ...

最新文章

  1. html显示三维模型restful,返回带有Flask Restful的呈现模板,在浏览器中显示HTML
  2. JAVA基础知识(5)
  3. 领域驱动设计,盒马技术团队这么做
  4. 只需20小时,让0基础的你掌握小程序云开发!这个暑假,约否?
  5. python三菱_三菱机器人melfarxm.ocx控件的Python使用,MelfaRxMOCX,python,用法
  6. python中的下划线用法
  7. 源码编译安装screen
  8. 方正国际用CMMI的思想管理博客
  9. 直角三角公式计算机,直角三角函数公式表
  10. 抓阄 计算机代表什么东西,周岁抓阄准备哪些东西
  11. 计算机论文研究思路怎么写,论文研究思路要写什么
  12. Request Method: OPTIONS
  13. 诈骗防范案例提醒:【韵⁢⁢达】您好, 因您用韵⁢⁢达收过12次,现复⁢制囗⁢令
  14. Adobe, 微软论剑 Flash, Silverlight 与 HTML5
  15. centos6.5环境基于conga的web图形化界面方式配置rhcs集群
  16. 【LINGO】lingo 软件简介
  17. js正则 匹配 汉字、数字、英文字母、下划线 正则表达式
  18. 如何在Win2000上安装配置防火墙(转)
  19. 内部类:No enclosing instance
  20. Tomcat启动后出现乱码

热门文章

  1. 5位数的数字黑洞是多少_五位数数字黑洞编程
  2. 怎样检测php语法错误,检查php的语法错误
  3. 将计算机与局域网互连 需要_,计算机与局域网连接需要的硬件是什么
  4. 华为云.通信云服务激活无限商业潜力
  5. lightbox灯箱效果
  6. 微软ime日文输入法每次切换英文和假名输入状态时,画面中央总有图片提示,怎么消掉
  7. 谈一下为什么程序员不要进外包吧
  8. 广东省计算机一级网络题分值,计算机一级考试分值分布
  9. 2019年电子设计国赛综合测评回顾
  10. 120_x轴与y轴平移【transform: translateX(n) translateY(n)】利用定位和变形使元素水平垂直居中