我是新手,多多包涵,有错误的请指出吧,如果有雷同,也多多包涵。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <assert.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>
/*工作结构体*/
typedef struct worker
{
void *(*process) (void *arg);
void *arg;
struct worker *next;
} CThread_worker;
/*线程池结构*/
typedef struct pool
{
pthread_mutex_t queue_lock;
pthread_cond_t queue_ready;
CThread_worker *queue_head;
int shutdown;
pthread_t *threadid;
int max_thread_num;
int cur_queue_size;
} CThread_pool;
/*定义两个路径的结构体*/
struct files
{
char sfilename[120];
char ofilename[120];
};
static struct files *CThread_files;
void *thread_routine (void *arg);
static CThread_pool *pool = NULL;
/*线程池初始化*/
void pool_init (int max_thread_num)
{
//线程池申请空间内存
pool = (CThread_pool *) malloc (sizeof (CThread_pool));
pthread_mutex_init (&(pool->queue_lock), NULL);
pthread_cond_init (&(pool->queue_ready), NULL);
pool->queue_head = NULL;
pool->max_thread_num = max_thread_num;
pool->cur_queue_size = 0;
pool->shutdown = 0;
pool->threadid = (pthread_t *) malloc (max_thread_num * sizeof (pthread_t));
int i = 0;
for (i = 0; i < max_thread_num; i++)
{
pthread_create (&(pool->threadid[i]), NULL, thread_routine,NULL);
}
}
/*向线程池中加入任务*/
void pool_add_worker (void *(*process) (void *arg), void *arg)
{
CThread_worker *newworker = (CThread_worker *) malloc (sizeof (CThread_worker));
newworker->process = process;
newworker->arg = arg;
newworker->next = NULL;
if(newworker==NULL)
{
printf("申请错误!");
exit(1);
}
pthread_mutex_lock (&(pool->queue_lock));
CThread_worker *member = pool->queue_head;
if (member != NULL)
{
while (member->next != NULL)
member = member->next;
member->next = newworker;
}
else
{
pool->queue_head = newworker;
}
assert (pool->queue_head != NULL);
pool->cur_queue_size++;
pthread_mutex_unlock (&(pool->queue_lock));
pthread_cond_signal (&(pool->queue_ready));
}
//删除线程池
int pool_destroy ()
{
int i;
pthread_cond_broadcast (&(pool->queue_ready));
for (i = 0; i < pool->max_thread_num; i++)
pthread_join (pool->threadid[i], NULL);
free (pool->threadid);
CThread_worker *head = NULL;
while (pool->queue_head != NULL)
{
head = pool->queue_head;
pool->queue_head = pool->queue_head->next;
free (head);
}
pthread_mutex_destroy(&(pool->queue_lock));
pthread_cond_destroy(&(pool->queue_ready));
free (pool);
pool=NULL;
return 0;
}
void *thread_routine (void *arg)
{
while (1)
{
pthread_mutex_lock (&(pool->queue_lock));
while (pool->cur_queue_size == 0 && pool->shutdown == 0)
{
//printf("wait\n");
printf ("starting thread id 0x%lu\n", pthread_self ());
pthread_cond_wait (&(pool->queue_ready), &(pool->queue_lock));
}
if (pool->cur_queue_size == 0 && pool->shutdown == 1)
{
printf("退出。。。。\n");
pthread_mutex_unlock (&(pool->queue_lock));
pthread_exit (NULL);
}
pool->cur_queue_size--;
CThread_worker *worker = pool->queue_head;
pool->queue_head = worker->next;
pthread_mutex_unlock (&(pool->queue_lock));
(*(worker->process)) (worker->arg);
if(pool->cur_queue_size==0)
pool->shutdown =1;
free (worker);
worker = NULL;
}
}
int mycopy_l(void *arg)
{
struct files *q=(struct files *)arg;
char buf[50];
int fb = open(q->sfilename, O_RDWR);
if(fb < 0)
{
perror("open fb failed\n");
return -1;
}
/*判断是否目标目录存在*/
//int cnt=access(q->ofilename,0);
//if(cnt==-1)
// mkdir(q->ofilename , right);
int fb2 = open(q->ofilename, O_RDWR|O_TRUNC|O_CREAT, 0777);
if(fb2 < 0)
{
perror("open fb2 failed\n");
return -1;
}
int cnt_r = 1,cnt_w = 1;
while(cnt_r != 0)
{
cnt_r = read(fb, buf, 50);
if(cnt_r < 0)
{
perror("read faild\n");
return -1;
}
cnt_w = write(fb2, buf, cnt_r);
if(cnt_w < 0)
{
perror("write failed\n");
return -1;
}
bzero(buf,sizeof(buf));
}
close(fb);
close(fb2);
return 0;
}
int mycopy(char *s,char *o)
{
char buf[50];
int fb = open(s, O_RDWR);
if(fb < 0)
{
perror("open fb failed\n");
return -1;
}
int fb2 = open(o, O_RDWR|O_TRUNC|O_CREAT, 0777);
if(fb2 < 0)
{
perror("open fb2 failed\n");
return -1;
}
int cnt_r = 1,cnt_w = 1;
while(cnt_r != 0)
{
cnt_r = read(fb, buf, 50);
if(cnt_r < 0)
{
perror("read faild\n");
return -1;
}
cnt_w = write(fb2, buf, cnt_r);
if(cnt_w < 0)
{
perror("write failed\n");
return -1;
}
bzero(buf,sizeof(buf));
}
close(fb);
close(fb2);
return 0;
}
int func(void *arg)
{
struct files *file1=(struct files *)arg;
struct dirent* p;
DIR *dir=opendir(file1->sfilename);
//在目录里遍历
while((p=readdir(dir)) != NULL)
{
if(p->d_name[0] == '.')
{
continue;
}
else
{
struct stat buf1;
CThread_files = malloc(sizeof( struct files));
sprintf(CThread_files->sfilename,"%s/%s",file1->sfilename,p->d_name);
if(lstat(CThread_files->sfilename,&buf1)<0)
{
printf("lstat error !!\n");
return -1;
}
else
{
if(S_ISDIR(buf1.st_mode))
{
sprintf(CThread_files->ofilename,"%s/%s",file1->ofilename,p->d_name);
//strcpy(CThread_files->ofilename , file1->ofilename);
mkdir(CThread_files->ofilename ,0777);
func((void *)CThread_files);
}
else
{
sprintf(CThread_files->ofilename,"%s/%s",file1->ofilename,p->d_name);
printf("源文件--》%s, 目标 --》%s\n",CThread_files->sfilename,CThread_files->ofilename);
pool_add_worker((void *)mycopy_l,(void *)CThread_files);
}
}
}
}
return 0;
}
int main (int argc, char **argv)
{
struct stat buf;
if(lstat(argv[1],&buf)<0)
{
printf("lstat error !!\n");
return -1;
}
if(S_ISREG(buf.st_mode))
{
mycopy(argv[1],argv[2]);
}
else
{
struct files *file1 = malloc(sizeof(struct files));
pool_init(3);
//让线程先跑
sleep(1);
sprintf(file1->sfilename,"%s",argv[1]);
sprintf(file1->ofilename,"%s",argv[2]);
func((void *)file1);
pool_destroy();
free (file1);//释放空间
file1=NULL;
}
return 0;
}