项目要求

1.基本

  用线程池实现一个大文件夹的拷贝,大文件夹嵌套很多小文件;实现复制到指定文件夹的全部文件夹。

2.扩充功能

  显示进度条;拷贝耗时统计;类似linux的tree,不能直接用system()与exec()等函数;根据文件类型拷贝;搜索文件;删除文件等。(暂时加了这么一些功能)

8月17日补:移动、复制到的目录已包含该文件则选择覆盖或者加命名。

实现思路

  先完成基本,逐步完成扩展再优化重构代码。

实现过程

基本功能

  基于linux,通过线程池实现的。核心就是线程池的三大基本功能--线程例程、添加线程、销毁线程池。由这三个为基础,对项目进行展开。基本功能,即通过递归读取目录,通过strucr dirent *p这个结构体来实现判断文件类型。如果是普通文件,直接在新目录用文件IO的读写实现拷贝功能(包括标准IO、系统IO,还有共享内存也可以实现),拷贝那里用“添加线程”,保证可以多线程实现拷贝;如果是目录文件,就先创建文件夹--mkdir(),再sprintf拼接字符串以及函数的递归实现子级目录的拷贝。

->拷贝代码

void *myregcp(void *myarg)
{
struct copypath *mypath=(struct copypath *)myarg; //系统IO的复制
int fd1,fd2;
fd1=open(mypath->oldpath,O_RDONLY);
fd2=open(mypath->newpath,O_CREAT|O_TRUNC|O_RDWR,0777);
if(fd1==-1)
{
perror("打开1失败\n");
return NULL;
}
if(fd2==-1)
{
perror("打开2失败\n");
return NULL;
}
char buf[SIZE];
int nread,nwrite;
while(1)
{
bzero(buf,SIZE);
nread=read(fd1,buf,SIZE);
if(nread==0)
break;
cs=cs+nread;
write(fd2,buf,nread);
}
close(fd1);
close(fd2);
return NULL;
}

->递归读取全部目录

int myreaddir(struct copypath *pp,struct threadpool *pool)
{
DIR *dirp=opendir(pp->oldpath);
if(dirp==NULL)
{
perror("失败:\n");
return -1;
}
struct dirent *p;
while((p=readdir(dirp))!=NULL)
{
if(p->d_type==DT_REG) //普通文件
{
struct copypath *mypath=malloc(sizeof(struct copypath));
sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
sprintf(mypath->newpath,"%s/%s",pp->newpath,p->d_name);
add_task(myregcp,mypath,pool); //实现
}
if(p->d_type==DT_DIR) //文件夹
{
if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
{
struct copypath *mydirpath=malloc(sizeof(struct copypath));
sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
sprintf(mydirpath->newpath,"%s/%s",pp->newpath,p->d_name);
mkdir(mydirpath->newpath,0777);
myreaddir(mydirpath,pool);
}
}
}
closedir(dirp);
return 1;
}

  这样就大概完成基本功能,用多线程实现大文件夹的拷贝。

扩充功能

->进度条

  定义两个全局变量,一个用于计算总字节数,另一个计算每次复制的字节数,再用一个显示函数实现进度条的显示。这里要注意缓冲区的问题,所以我用了"fflush(NULL)"这个函数,让它每打印一个'|'的时候,就刷新一次缓冲区。计算总的字节数直接递归全部目录,用"struct stat info"这个结构体里面的"info.st_size"累加,即可得到总的字节数;拷贝功能函数里面有个"cs"变量,就是存放拷贝字节数。显示进度条就用简单的判断,加相除实现。因为是显示20个|,所以我乘20。

  num=(float)cs;        //正在复制字节数
  k=(num/s)*20;

->耗时

  有三种思路,用clock()、time()、sleep(1)等都可以实现计时,直接在拷贝前和拷贝后加赋值,然后相减,即可。起初自己是用clock()这个函数,但是每次都是三秒。。。然后转到sleep(),让它自己while()累加实现。

->代码实现树

  还是递归的思想,递归如果是普通文件就打印,是目录文件夹就字符串拼接再递归打印子文件夹下的子文件。

void dirtree(char dirpath[],int level)
{
int i;
char *dirname=NULL;
int dirlen;
DIR *dp=opendir(dirpath);
if(dp==NULL)
{
perror("失败:\n");
return;
}
struct dirent *ep;
while((ep=readdir(dp))!=NULL)
{
if(strncmp(ep->d_name, ".", 1) == 0)
continue;
for(i=0;i<level;i++)
{
printf("|");
printf(" ");
}
printf("|--- ");
printf("\033[1;32;40m %s \033[0m\n",ep->d_name);
if(ep->d_type==DT_DIR)
{
//当前目录长度
dirlen=strlen(dirpath)+1;
//备份
dirname=(char *)malloc(dirlen);
memset(dirname,0,dirlen);
memcpy(dirname,dirpath,dirlen); strcat(dirpath,"/");
strcat(dirpath,ep->d_name);
dirtree(dirpath,level+1); //递归实现树效果
//恢复之前的目录名
memcpy(dirpath,dirname,dirlen);
free(dirname);
dirname = NULL;
}
}
closedir(dp);
}

->按类型拷贝文件

  也比较简单,另建一个递归读目录的函数,在普通文件加个if条件判断就可以。

  if(strstr(p->d_name,ftype)!=NULL)

->搜索文件

  类似于win的文件检索功能,在输入那个文件下面实现相似文件名的检索,并打印相关路径。也是递归读取目录,核心的改变代码也就一句。用"strstr()"寻找相应的子字符串,打印。

  if(strstr(p->d_name,filename)!=NULL)

->删除文件夹

  删除稍微要注意一下如果文件夹下面还有其他文件,就不能直接用"rmdir"删除文件夹。先用remove()删除文件,之后再删除子文件夹。也是用递归思想实现的。

实现效果

  现在还传不了,后期再传吧。

全部代码

#include "myhead.h"
#define SIZE 1024*1024
long int s=0; //总字节数
long int cs=0; //计算每次复制的字节数
int tm=0; //计时--以秒为单位
int flag; //结束标志位
/***************************相关结构体的定义******************************/
struct copypath
{
char oldpath[256];
char newpath[256];
char target[50];
};
//创建任务链表结构体
struct tasklist
{
void *(*taskp)(void *);
void *taskarg;
struct tasklist *next;
};
//创建任务链表表头
struct tasklist *myhead;
//初始化任务链表
struct tasklist* task_init()
{
struct tasklist *mytask=malloc(sizeof(struct tasklist));
mytask->taskp=NULL;
mytask->taskarg=NULL;
mytask->next=NULL;
return mytask;
}
//创建线程池
struct threadpool
{
int threadnum;//统计当前线程数量
pthread_t *threadid;//存放当前线程的ID号
struct tasklist *taskhead;//保存任务链表的头结点
pthread_mutex_t threadmutex;//互斥锁
int tasknum;//统计任务链表中的数量
pthread_cond_t threadcond;//条件变量
bool threadflag;//用于判断线程池是否开启
}; //线程的多任务函数
void *routine(void *arg)
{
struct threadpool *pool=(struct threadpool *)arg;
//负责从任务链表的头结点的下一个位置取出任务然后处理
struct tasklist *p;
while(1)
{
//上锁
pthread_mutex_lock(&(pool->threadmutex));
//判断数量是否为0
while(pool->threadflag==true && pool->tasknum==0)
{
//printf("%ld线程阻塞--wait\n",pthread_self());
pthread_cond_wait(&(pool->threadcond),&(pool->threadmutex));
}
if(pool->threadflag==false&&pool->tasknum==0)
{
pthread_mutex_unlock(&(pool->threadmutex));
pthread_exit(NULL);
}
//取出节点处理
p=pool->taskhead->next;
pool->taskhead->next=p->next;
p->next=NULL;
//更新任务数量
pool->tasknum--;
//printf("%ld线程正在执行任务\n",pthread_self());
//解锁
pthread_mutex_unlock(&(pool->threadmutex));
(p->taskp)(p->taskarg);
free(p);
}
}
//初始化线程池结构体
struct threadpool *thread_init(int num)
{
struct threadpool *mythread=malloc(sizeof(struct threadpool));//申请堆空间
mythread->threadnum=num;
mythread->threadid=malloc(num*sizeof(pthread_t));
//初始化链表的表头
mythread->taskhead=myhead;
//锁初始化
pthread_mutex_init(&(mythread->threadmutex),NULL);
//条件变量初始化
pthread_cond_init(&(mythread->threadcond),NULL);
mythread->tasknum=0;
mythread->threadflag=true;
for(int i=0;i<num;i++)
pthread_create(&(mythread->threadid[i]),NULL,routine,mythread);
return mythread;
}
//添加任务函数
int add_task(void *(*p)(void *),void *newarg,struct threadpool *pool)
{
//找到尾部
struct tasklist *q=pool->taskhead;
while(q->next!=NULL)
q=q->next;
//准备新结点
struct tasklist *newnode=malloc(sizeof(struct tasklist));
newnode->taskp=p;
newnode->taskarg=newarg;
newnode->next=NULL; //上锁
pthread_mutex_lock(&(pool->threadmutex));
//尾插
q->next=newnode;
//更新任务数量
pool->tasknum++;
pthread_mutex_unlock(&(pool->threadmutex));
//唤醒条件
pthread_cond_signal(&(pool->threadcond));
return 0;
}
/***************************************************************************/
// 功能函数
/***************************************************************************/
//主目录名
void *mycopyname(void *myarg)
{
struct copypath *mypath=(struct copypath *)myarg;
char fpath[15]; //求出主目录的名字
char temp[100];
strcpy(temp,mypath->oldpath);
char *p=strtok(temp,"/");
//获取文件名
while(p!=NULL)
{
bzero(fpath,15);
strcpy(fpath,p);
p=strtok(NULL,"/");
}
strcpy(((struct copypath *)myarg)->target,fpath);
}
//普通文件复制
void *myregcp(void *myarg)
{
struct copypath *mypath=(struct copypath *)myarg; //系统IO的复制
int fd1,fd2;
fd1=open(mypath->oldpath,O_RDONLY);
fd2=open(mypath->newpath,O_CREAT|O_TRUNC|O_RDWR,0777);
if(fd1==-1)
{
perror("打开1失败\n");
return NULL;
}
if(fd2==-1)
{
perror("打开2失败\n");
return NULL;
}
char buf[SIZE];
int nread,nwrite;
while(1)
{
bzero(buf,SIZE);
nread=read(fd1,buf,SIZE);
//cs=cs+nread;
if(nread==0)
break;
cs=cs+nread;
write(fd2,buf,nread);
}
close(fd1);
close(fd2);
return NULL;
}
//遍历读目录
int myreaddir(struct copypath *pp,struct threadpool *pool)
{
DIR *dirp=opendir(pp->oldpath);
if(dirp==NULL)
{
perror("失败:\n");
return -1;
}
struct dirent *p;
while((p=readdir(dirp))!=NULL)
{
if(p->d_type==DT_REG) //普通文件
{
struct copypath *mypath=malloc(sizeof(struct copypath));
sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
sprintf(mypath->newpath,"%s/%s",pp->newpath,p->d_name);
add_task(myregcp,mypath,pool); //实现
}
if(p->d_type==DT_DIR) //文件夹
{
if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
{
struct copypath *mydirpath=malloc(sizeof(struct copypath));
sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
sprintf(mydirpath->newpath,"%s/%s",pp->newpath,p->d_name);
mkdir(mydirpath->newpath,0777);
myreaddir(mydirpath,pool);
}
}
}
closedir(dirp);
return 1;
}
//递归算字节数
int size_sum(struct copypath *pp)
{
DIR *dirp=opendir(pp->oldpath);
if(dirp==NULL)
{
perror("失败:\n");
return -1;
}
struct dirent *p;
struct stat info;
while((p=readdir(dirp))!=NULL)
{
if(p->d_type==DT_REG) //普通文件
{
struct copypath *mypath=malloc(sizeof(struct copypath));
sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
//计算字节数
stat(mypath->oldpath,&info);
s=s+info.st_size;
}
if(p->d_type==DT_DIR) //文件夹
{
if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
{
struct copypath *mydirpath=malloc(sizeof(struct copypath));
sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
size_sum(mydirpath);
}
}
}
closedir(dirp);
return 1;
}
//实现进度条
void *pro_bar(void *myarg)
{
int i,j=0;
float k,num;
printf("进度:");
while(1)
{
j=k;
num=(float)cs; //正在复制字节数
k=(num/s)*20; //
k=(int)k;
if(k-j>=1)
{
for(i=0;i<k-j;i++)
{
printf("\033[1;31;42m | \033[0m");
}
fflush(NULL);
}
usleep(10000);
if(s==cs)
{
printf("\033[1;31;42m | \033[0m");
fflush(NULL);
usleep(200);
break;
}
}
printf("\n任务完成\n");
return NULL;
}
//lseep计时
void *my_time(void *myarg)
{
while(1)
{
sleep(1);
tm++;
if(s==cs)
{
break;
}
}
}
//显示选择拷贝类型界面
int showdow()
{
int n;
printf("**********************\n");
printf(" 请输入你要拷贝的文件 \n");
printf(" 1.复制全部文件; \n");
printf(" 2.选择类型复制; \n");
printf(" 3.原目录文件树; \n");
printf(" 4.查找某个文件; \n");
printf(" 5.删除某个文件. \n");
printf("**********************\n");
scanf("%d",&n);
return n;
}
//递归读取文件类型的字节数
int ftypesize_sum(struct copypath *pp,char *ftype)
{
DIR *dirp=opendir(pp->oldpath);
if(dirp==NULL)
{
perror("失败:\n");
return -1;
}
struct dirent *p;
struct stat info;
while((p=readdir(dirp))!=NULL)
{
if(p->d_type==DT_REG) //普通文件
{
if(strstr(p->d_name,ftype)!=NULL) //文件类型
{
struct copypath *mypath=malloc(sizeof(struct copypath));
sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
//计算字节数
stat(mypath->oldpath,&info);
s=s+info.st_size;
}
}
if(p->d_type==DT_DIR) //文件夹
{
if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
{
struct copypath *mydirpath=malloc(sizeof(struct copypath));
sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
ftypesize_sum(mydirpath,ftype);
}
}
}
closedir(dirp);
return 1;
}
//递归读取文件类型的目录
int myftyper(struct copypath *pp,struct threadpool *pool,char *ftype)
{
DIR *dirp=opendir(pp->oldpath);
if(dirp==NULL)
{
perror("失败:\n");
return -1;
}
struct dirent *p;
while((p=readdir(dirp))!=NULL)
{
if(p->d_type==DT_REG) //普通文件
{
if(strstr(p->d_name,ftype)!=NULL)
{
struct copypath *mypath=malloc(sizeof(struct copypath));
sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
sprintf(mypath->newpath,"%s/%s",pp->newpath,p->d_name);
add_task(myregcp,mypath,pool); //实现
}
}
if(p->d_type==DT_DIR) //文件夹
{
if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
{
struct copypath *mydirpath=malloc(sizeof(struct copypath));
sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
sprintf(mydirpath->newpath,"%s/%s",pp->newpath,p->d_name);
mkdir(mydirpath->newpath,0777);
myftyper(mydirpath,pool,ftype);
}
}
}
closedir(dirp);
return 1;
}
//树实现
void dirtree(char dirpath[],int level)
{
int i;
char *dirname=NULL;
int dirlen;
DIR *dp=opendir(dirpath);
if(dp==NULL)
{
perror("失败:\n");
return;
}
struct dirent *ep;
while((ep=readdir(dp))!=NULL)
{
if(strncmp(ep->d_name, ".", 1) == 0)
continue;
for(i=0;i<level;i++)
{
printf("|");
printf(" ");
}
printf("|--- ");
printf("\033[1;32;40m %s \033[0m\n",ep->d_name);
if(ep->d_type==DT_DIR)
{
//当前目录长度
dirlen=strlen(dirpath)+1;
//备份
dirname=(char *)malloc(dirlen);
memset(dirname,0,dirlen);
memcpy(dirname,dirpath,dirlen); strcat(dirpath,"/");
strcat(dirpath,ep->d_name);
dirtree(dirpath,level+1); //递归实现树效果
//恢复之前的目录名
memcpy(dirpath,dirname,dirlen);
free(dirname);
dirname = NULL;
}
}
closedir(dp);
} //递归查找相似文件-查找文件
int sc_file(struct copypath *pp,char *filename)
{
DIR *dirp=opendir(pp->oldpath);
if(dirp==NULL)
{
perror("失败:\n");
return -1;
}
struct dirent *p;
while((p=readdir(dirp))!=NULL)
{
if(p->d_type==DT_REG) //普通文件
{
if(strstr(p->d_name,filename)!=NULL) //文件类型
{
struct copypath *mypath=malloc(sizeof(struct copypath));
sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
printf("已找到文件路径:%s\n",mypath->oldpath);
free(mypath);
}
}
if(p->d_type==DT_DIR) //文件夹
{
if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
{
if(strstr(p->d_name,filename)!=NULL) //文件类型
{
struct copypath *mypath1=malloc(sizeof(struct copypath));
sprintf(mypath1->oldpath,"%s/%s",pp->oldpath,p->d_name);
printf("已找到文件路径:%s\n",mypath1->oldpath);
free(mypath1);
}
struct copypath *mydirpath=malloc(sizeof(struct copypath));
sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
sc_file(mydirpath,filename);
}
}
}
closedir(dirp);
return 1;
}
//删除--文件\文件夹
int alldet(struct copypath *pp)
{
DIR *dirp=opendir(pp->oldpath);
struct dirent *p;
while((p=readdir(dirp))!=NULL)
{
if(p->d_type==DT_REG) //普通文件
{
struct copypath *mypath=malloc(sizeof(struct copypath));
sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
remove(mypath->oldpath);
}
if(p->d_type==DT_DIR) //文件夹
{
if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
{
struct copypath *mydirpath=malloc(sizeof(struct copypath));
sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
alldet(mydirpath);
rmdir(mydirpath->oldpath);
}
}
}
closedir(dirp);
rmdir((pp->oldpath));
return 1;
}
/***************************************************************************/ /***************************************************************************/
// 简化主程序
/***************************************************************************/
int simcopy_all(struct threadpool *mypool) //简化主程序--复制全部
{
tm=s=cs=0;
struct copypath paths; //新旧路径结构体
printf("请输入源文件\n");
scanf("%s",paths.oldpath);
printf("请输入目标文件\n");
scanf("%s",paths.newpath);
mycopyname(&paths);
sprintf(paths.newpath,"%s/%s",paths.newpath,paths.target);
mkdir(paths.newpath,0777);
size_sum(&paths); //计算字节数
usleep(20);
printf("总字节数:%ld\n",s);
add_task(my_time,NULL,mypool);
add_task(pro_bar,NULL,mypool);
myreaddir(&paths,mypool);
}
void simcopy(struct threadpool *mypool) //简化主程序--按文件类型复制
{
tm=s=cs=0;
char ftype[6]; //文件类型变量
struct copypath paths;
printf("请输入源文件\n");
scanf("%s",paths.oldpath);
printf("请输入目标文件\n");
scanf("%s",paths.newpath);
mycopyname(&paths);
sprintf(paths.newpath,"%s/%s",paths.newpath,paths.target);
mkdir(paths.newpath,0777);
printf("请输入要复制的文件类型,如.txt等\n");
scanf("%s",ftype);
ftypesize_sum(&paths,ftype);
printf("总字节数:%ld\n",s);
usleep(20);
add_task(my_time,NULL,mypool);
add_task(pro_bar,NULL,mypool);
myftyper(&paths,mypool,ftype);
}
void simtree() //简化主程序--文件树
{
char direntName[256];
struct copypath paths;
printf("请输入源文件\n");
scanf("%s",paths.oldpath);
memset(direntName, 0, sizeof(direntName));
strcat(direntName, paths.oldpath);
printf("%s\n",paths.oldpath);
dirtree(direntName, 0);
}
void myscfile() //简化主程序--查找
{
char fname[256];
struct copypath paths;
printf("请输入查找文件夹名\n");
scanf("%s",paths.oldpath);
printf("请输入要查找的文件名\n");
scanf("%s",fname);
sc_file(&paths,fname);
usleep(10);
}
void mydel() //简化主程序--删除
{
tm=s=cs=0;
char delfile[100];
struct copypath paths;
printf("请输入要删除的文件夹\n");
scanf("%s",paths.oldpath);
size_sum(&paths); //计算字节数
printf("size is: %ld\n",s);
alldet(&paths);
usleep(10);
}
void endshow() //简化主程序--结束
{
printf("请输入 \n");
printf(" 1--继续 \n");
printf(" 2--退出 \n");
scanf("%d",&flag);
}
/***************************************************************************/
//销毁线程池
int pool_destroy(struct threadpool *pool)
{
int i;
//改变标志位,让线程退出死循环
pool->threadflag=false;
//唤醒所有线程
pthread_cond_broadcast(&(pool->threadcond));
//回收所有线程
for(i=0;i<pool->threadnum;i++)
{
pthread_join(pool->threadid[i],NULL);
//printf("%ld线程已被回收\n",pool->threadid[i]);
}
return 0;
} int main()
{
struct copypath paths;
while(1)
{
flag=0;
system("clear");
myhead=task_init(); //初始化任务链表的表头
struct threadpool *mypool=thread_init(10); //创建并初始化线程池
int ret=showdow();
switch(ret)
{
case 1: //拷贝全部
simcopy_all(mypool);
pool_destroy(mypool); //线程池的销毁
printf("拷贝花费:%d seconds\n",tm);
break;
case 2: //拷贝部分
simcopy(mypool);
pool_destroy(mypool);
printf("拷贝花费:%d seconds\n",tm);
break;
case 3: //显示文件树
simtree();
break;
case 4: //查找某个文件--显示相似的文件
myscfile();
break;
case 5: //删除某个文件夹
mydel();
printf("delete done\n");
break;
default:
break;
}
endshow();
if(flag==1)
continue;
else if(flag==2)
break;
}
system("clear");
usleep(20);
return 0;
}

码源:

http://pan-yz.chaoxing.com/share/info/b54be58ad063e1e9

有什么建议,欢迎联系。邮箱:2460576606@qq.com

基于linux与线程池实现文件管理的更多相关文章

  1. 开源项目SMSS开发指南(二)——基于libevent的线程池

    libevent是一套轻量级的网络库,基于事件驱动开发.能够实现多线程的多路复用和注册事件响应.本文将介绍libevent的基本功能以及如何利用libevent开发一个线程池. 一. 使用指南 监听服 ...

  2. linux C 线程池(物不可穷也~)

    Linux 多线程编程之 线程池 的原理和一个简单的C实现,提高对多线程编 程的认知,同步处理等操作,以及如何在实际项目中高效的利用多线程开 发. 1.  线程池介绍 为什么需要线程池??? 目前的大 ...

  3. Linux pthread 线程池实现

    基于pthread封装了一个简易的ThreadPool,具有以下特性: 1.具有优先级的任务队列 2.线程池大小可以二次调整,增加线程或者删除空闲线程 3.任务两种重写方式,重写run或者使用函数回调 ...

  4. Linux C++线程池实例

    想做一个多线程服务器测试程序,因此参考了github的一些实例,然后自己动手写了类似的代码来加深理解. 目前了解的线程池实现有2种思路: 第一种: 主进程创建一定数量的线程,并将其全部挂起,此时线程状 ...

  5. 基于hystrix的线程池隔离

    hystrix进行资源隔离,其实是提供了一个抽象,叫做command,就是说,你如果要把对某一个依赖服务的所有调用请求,全部隔离在同一份资源池内 对这个依赖服务的所有调用请求,全部走这个资源池内的资源 ...

  6. Linux C++线程池

    .为什么需要线程池? 部分应用程序需要执行很多细小的任务,对于每个任务都创建一个线程来完成,任务完成后销毁线程,而这就会产生一个问题:当执行的任务所需要的时间T1小于等于创建线程时间T2和销毁线程时间 ...

  7. Linux下线程池的理解与简单实现

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

  8. 基于C++11线程池

    1.包装线程对象 class task : public std::tr1::enable_shared_from_this<task> { public: task():exit_(fa ...

  9. Linux简单线程池实现(带源码)

    这里给个线程池的实现代码,里面带有个应用小例子,方便学习使用,代码 GCC 编译可用.参照代码看下面介绍的线程池原理跟容易接受,百度云下载链接: http://pan.baidu.com/s/1i3z ...

随机推荐

  1. 树莓派使用python+继电器控制220V灯泡

    需要的材料 1.继电器:继电器是一种电控制器件,它实际上是用小电流去控制大电流运作的一种"自动开关",我们这里用它来控制电灯.控制了继电器就等于控制了电灯. 我购买的是某宝上3块钱 ...

  2. PLSQL安装,PLSQL汉化,激活

    一)准备工作 1.点击下载PLSQL:https://www.allroundautomations.com/registered-plsqldev/.本次安装的是12.0.7,安装版本为64位 2. ...

  3. 如何在 Serverless K8s 集群中低成本运行 Spark 数据计算?

    作者 | 柳密 阿里巴巴阿里云智能 ** 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复"入门",即可获取 ...

  4. Mysql双主双从高可用集群的搭建且与MyCat进行整合

    1.概述 老话说的好:瞻前顾后.患得患失只会让我们失败,下定决心,干就完了. 言归正传,之前我们聊了Mysql的一主一从读写分离集群的搭建,虽然一主一从或一主多从集群解决了并发读的问题,但由于主节点只 ...

  5. MIPS流水线技术

    华中科技大学 - 计算机硬件系统设计 单周期指令运行动态 Instruction Fetch Instruction Decode Execution MEM Write Back 单周期时空图 设耗 ...

  6. PublishFolderCleaner 让你的 dotnet 应用发布文件夹更加整洁

    大家都知道,在 dotnet 发布时,将会在输出的 publish 文件夹包含所需的依赖.在 .NET Core 开始,引入了 AppHost 的概念,即使是单个程序集,也需要独立的 Exe 可执行文 ...

  7. C语言中while 语句

    while的执行顺序 while 循环的执行顺序非常简单,它的格式是: while (表达式) { 语句: } 概念:当表达式为真,则执行下面的语句:语句执行完之后再判断表达式是否为真,如果为真,再次 ...

  8. 【Java虚拟机3】类加载器

    前言 Java虚拟机设计团队有意把类加载阶段中的"通过一个类的全限定名来获取描述该类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需的类. ...

  9. SpringCloud-初见

    目录 前言 微服务概述 微服务与微服务架构 微服务优缺点 微服务技术栈 为什么选择SpringCloud作为微服务架构 SpringCloud入门 SpringCloud和SpringBoot的关系 ...

  10. 欧姆龙PLC HostLink协议整理

    欧姆龙PLC HostLink协议整理 1.常用的存储器功能区 CIO: 输入继电器  272 点(17 CH) 0.00-16.15 输出继电器  272 点(17 CH) 100.00-116.1 ...