线程池与cp命令的实现
来源:互联网 发布:php防止sql注入代码 编辑:程序博客网 时间:2024/04/26 20:39
用Linux C完成shall命令cp的实现
在复制大量文件时,当遇到大量的或较大的文件时,使用单进程单线程进行文件复制效率比较低下,而使用线程池能很好的提高效率。
思路:
1、初始化线程池2、如果需要复制文件则直接复制,如果需要复制文件夹则往下3、遍历文件夹,复制内容4、复制内容任务加入任务链表
线程池
线程池结构体
struct thread_pool{ pthread_mutex_t mutex;//互斥锁 pthread_cond_t cond;//条件变量 int thread_num;//线程池中线程的数量 pthread_t *t;//每个线程的ID struct task *head;//任务链表头 int cur_queue_size;//任务节点数};
任务结构体
struct task{ void *(*p)(struct tem *);//函数指针 struct tem *arg;//参数实参 struct task *next;//下一个任务的地址};
在此任务链表为单向链表
主程序
#include "mycp.h"int all_pthread_done = 0;int main (int argc ,char **argv){ struct stat st; pool_init(4);//初始化线程池 printf("init pool\n"); sleep(1); stat(argv[1],&st); struct tem t;//因为线程函数只能传入一个参数所以定义tem结构体包含源目录与目的目录 t.t_s = argv[1]; t.t_o = argv[2]; if (S_ISDIR(st.st_mode))//判断是否为目录 show_dir(argv[1],argv[2]); else//为文件的话直接复制 { copy_file(t); } all_pthread_done = 1;//告诉子线程所有任务添加完成 printf("finsh!!\n"); pthread_cond_broadcast(&(pool->cond));//唤醒在等待的线程 int i; for(i=0;i<pool->thread_num;i++) pthread_join(pool->t[i],NULL);//等待所有线程退出 printf("end\n"); pool_del();//回收线程等 return 0;}
函数
#include "mycp.h"extern int all_pthread_done ;int already_get_tem = 0;void pool_add_task(void *(*pr)(struct tem *),struct tem arg) //添加任务{ struct task *newtask=malloc(sizeof(struct task));//创建,初始化任务 newtask->p = pr; newtask->arg = arg; newtask->next = NULL; pthread_mutex_lock(&(pool->mutex));//上锁 printf("add task ing cp %s to %s\n",arg.t_s,arg.t_o ); //把newtask节点增加到任务链表尾。 struct task *temp = NULL; if(pool->head==NULL) pool->head = newtask; else { temp = pool->head; pool->head = newtask; newtask->next = temp; } printf("add task fin cp %s to %s\n",newtask->arg.t_s,newtask->arg.t_o ); pool->cur_queue_size++;//任务增加一个 pthread_mutex_unlock(&(pool->mutex)); pthread_cond_signal(&(pool->cond));//告诉子线程任务添加完毕 printf("add task successful!!\n");}void *f(void *reg) //子线程{ struct task *wh; while(1) { pthread_mutex_lock(&(pool->mutex)); printf("wait for task\n"); while((pool->cur_queue_size==0)&&(all_pthread_done==0))//等待任务 pthread_cond_wait(&(pool->cond),&(pool->mutex)); if ((pool->cur_queue_size==0)&&(all_pthread_done==1))//如果没有任务切主线程添加任务完毕则退出 { pthread_mutex_unlock(&(pool->mutex)); printf("pthread exit\n"); pthread_exit(0); } wh = pool->head; // 将任务从任务列表中取出 pool->head = wh->next; pool->cur_queue_size--; printf("get the task %s to %s\n", wh->arg.t_s,wh->arg.t_o); pthread_mutex_unlock(&(pool->mutex));//读取完节点后解锁 (*(wh->p))(&(wh->arg));//执行任务 printf("copy finsh\n"); free(wh);//释放任务 }}void pool_init(int num){ pool = (struct thread_pool *)malloc(sizeof(struct thread_pool));//初始化线程池 pthread_mutex_init(&(pool->mutex),NULL);//初始化互斥锁 pthread_cond_init(&(pool->cond),NULL);//初始化条件变量 pool->thread_num=num; pool->head=NULL; pool->cur_queue_size=0; pool->t = malloc(sizeof(pthread_t)*num);//建立数组,元素有num个 int i; for(i=0;i<pool->thread_num;i++) pthread_create(&(pool->t[i]),NULL,f,&i);//建立三个线程,线程号为pool->t}char * arr(char *frr,char *crr)//{ int i = strlen(crr); int j = strlen(frr); char *a = malloc(sizeof(char)*(i+j+1+1)); sprintf(a,"%s/%s",frr,crr); printf("arr a = %s\n", a); return a;}char * arr_file(char *frr,char *crr){ int i = strlen(crr); int j = strlen(frr); char *a = malloc(sizeof(char)*(i+j+1+1)); if (frr[strlen(frr)]=='/') sprintf(a,"%s%s",frr,crr); else sprintf(a,"%s/%s",frr,crr); printf("arr_file a: %s\n", a); return a;}char *arr_m(char *mdir,char *pdir){ if (mdir[0]=='.') { int i = 0,j; j = strlen(mdir)+1; printf("star %d j = %d, %c \n", i,j,mdir[0]); sleep(1); while(i < j) { sleep(1); mdir[i] = mdir[++i]; printf("%d\n",i ); } } char *a = malloc(sizeof(char)*(strlen(mdir)+strlen(pdir)+1)); sprintf(a,"%s%s",pdir,mdir); printf("arr_m a = %s\n", a); sleep(3); return a;}void * copy(struct tem *te){ printf("copying %s ..to.. %s\n", te->t_s,te->t_o); int fd1 ,fd2,i=1024; fd1 = open(te->t_s,O_RDONLY); char buf[1024]; fd2 = open(te->t_o,O_RDWR|O_CREAT , 0777); while(i == 1024) { i = read(fd1,buf,1024); write(fd2,buf,i); } free(te->t_s); free(te->t_o);}void copy_file(struct tem te){ printf("%s to %s\n",te.t_s,te.t_o ); char *c = malloc(sizeof(char)*(strlen(te.t_o)+1)); strcpy(c,te.t_o); printf("c = %s\n", c); int i ; for (i = strlen(te.t_o);c[i]!='/';i--); c[i] = '\0'; mkdir(c,0777); int fd1 ,fd2; i=1024; fd1 = open(te.t_s,O_RDONLY); char buf[1024]; fd2 = open(te.t_o,O_RDWR|O_CREAT , 0777); while(i == 1024) { i = read(fd1,buf,1024); write(fd2,buf,i); } free(C);}void show_dir(char *mdir,char *pdir)//遍历目录 ./123 ./456 ./123/555 ./456/555{ char *temp,*temp2; struct dirent * da; struct tem tem; DIR * dir = NULL; printf("mkdiring pdir %s ...\n", pdir); dir = opendir(mdir); if(mkdir(pdir,0777)==-1)//先创建目的目录 ./456 ./456/555 { printf("dir is already exists\n"); } sleep(1); while(da = readdir(dir)) { if(da->d_name[0]=='.') continue; if((int)da->d_type==4)//判断原目录下的文件是目录还是普通文件 ./123/555 { temp = arr(mdir,da->d_name);//得到完整的目录路径 ./123/555 temp2 = arr(pdir,da->d_name);//得到完整的目的目录路径./456/555 show_dir(temp,temp2); free(temp); free(temp2); }else { tem.t_s = arr_file(mdir,da->d_name);//得到完整的原文件路径 tem.t_o = arr_file(pdir,da->d_name);//得到完整的目的文件路径 pool_add_task(copy,tem);//添加copy任务 //copy(&tem); //使用线程去做 } } closedir(dir);}void pool_del(void){ pthread_mutex_destroy(&(pool->mutex)); pthread_cond_destroy(&(pool->cond)); free(pool->t); free(pool);}
mycp.h
#ifndef _MYCP_H_#define _MYCP_H_#include <stdio.h>#include <pthread.h>#include <sys/types.h>#include <dirent.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>struct tem{ char *t_s; char *t_o;};struct task{ void *(*p)(struct tem *); struct tem arg;//参数实参 struct task *next;};struct thread_pool{ pthread_mutex_t mutex; pthread_cond_t cond; int thread_num; pthread_t *t; struct task *head; int cur_queue_size;//任务节点数};struct thread_pool *pool;void pool_add_task(void *(*pr)(struct tem *),struct tem arg); //增加任务void *f(void *reg); //子线程void pool_init(int num);void pool_del(void);void * copy(struct tem *te);void show_dir(char *mdir,char *pdir);char *arr_m(char *mdir,char *pdir);char * arr_file(char *frr,char *crr);char * arr(char *frr,char *crr);void copy_file(struct tem te);#endif
0 0
- 线程池与cp命令的实现
- cp命令的介绍与实现
- cp命令的实现
- cp命令的实现
- linux 的cp命令实现
- linux cp 命令的实现
- 简单cp命令的实现
- 线程实现cp-r与ls-l
- CP命令的较完整的实现
- 实现cp命令–文件夹的拷贝
- 实现一个简单的cp命令
- 文件复制命令CP 的简单实现
- 文件读写,cp命令的实现
- Linux文件复制cp命令的实现
- cp命令实现
- linux cp 命令实现
- cp命令C实现
- linux命令实现:cp
- 协同过滤算法python实现简单入门详细注释
- 2946: [Poi2000]公共串 二分+hash
- find、grep、wc使用方法简单总结
- hdu 2842 Chinese Rings(矩阵递推)
- VS2012 scanf()运行通不过的时候,提示需要使用scanf_s()的解决办法。
- 线程池与cp命令的实现
- Android 异常解决 content.ActivityNotFoundException: Unable to find explicit activity class
- Unity Notes之协程(Coroutine)简析
- 【LeetCode OJ 242】Valid Anagram
- 路漫漫其修远兮吾将上下而求索
- Vijos P1097 合并果子(优先队列 贪心)
- MFC打开文件对话框
- 【Android源码-PMS】(二)ComponentInfo类
- Python进程和线程