#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include "include.h"
//利用线程池实现文件复制(多文件),在每个子线程中创建线程实现分块复制
//定义任务节点
#define BLOCKSIZE 512
typedef struct workernode
{
void * (*work)(void *arg);
void * arg;
struct workernode *next;
}workernode;
//定义线程池结构
typedef struct threadpool
{
int maxnum;
int shutdown;
pthread_t *thread;
workernode * work;
int worknum;
pthread_mutex_t mutex;
pthread_cond_t cond;
}threadpool;
threadpool *pool;
typedef struct
{
int sfd;//源文件标志(读)
int dfd;//目标文件标志(写)
int start; //读文件 起始位置
int end;//读文件 ,结束位置
}copyblock;
pthread_mutex_t mutex;
void run()
{
while(1)
{
pthread_mutex_lock(&pool->mutex);
if(pool->worknum==0 &&(!pool->shutdown))
{
pthread_cond_wait(&pool->cond,&pool->mutex);
//子线程堵塞
}
if(pool->shutdown)
{
printf("aaa\n");
pthread_mutex_unlock(&pool->mutex);
//此处的解锁是当有一个线程执行到任务0的时候,其他的线程已经没有任务,
//要是没有解锁 的话就会没法退出
pthread_exit(0);
}
workernode* tmp=pool->work;
pool->work=tmp->next;
printf("%d\n",pool->worknum);
pool->worknum--;
tmp->next=NULL;
(*(tmp->work))(tmp->arg);
//printf("123\n");
pthread_mutex_unlock(&pool->mutex);
sleep(1);
}
}
void init_pool(int num)
{
pool=(threadpool*)malloc(1*sizeof(threadpool));
pthread_mutex_init(&pool->mutex,NULL);
pthread_cond_init(&pool->cond,NULL);
pool->shutdown=0;//启用
pool->maxnum=num;
pool->work=NULL;
pool->worknum=0;
pool->thread=(pthread_t*)malloc(num*sizeof(pthread_t));
int i;
for(i=0;i<num;i++)
{z
pthread_create(&pool->thread[i],NULL,(void*)run,NULL);
}
sleep(1);//堵塞主线程,让子线程运行
}
void init_task(void * (*work)(void *arg),void *arg)
{
workernode *task=(workernode*)malloc(1*sizeof(workernode));
task->work=work;
task->arg=arg;
task->next=NULL;
workernode *tmp=pool->work;
if(tmp==NULL)
{
pool->work=task;
task=NULL;
}
else
{
while(tmp->next!=NULL)
{
tmp=tmp->next;
}
tmp->next=task;
task=NULL;
}
pool->worknum++;
pthread_cond_signal(&pool->cond);
}
void pool_destroy()
{
if(pool->shutdown==1)
return;
pool->shutdown=1;
pthread_cond_broadcast(&pool->cond);
int i;
for(i=0;i<3;i++)
{
pthread_join(pool->thread[i],NULL);
}
free(pool->thread);
pool->thread=NULL;
pthread_mutex_destroy(&pool->mutex);
pthread_cond_destroy(&pool->cond);
free(pool);
pool=NULL;
}
void copyfile(void * arg)
{
pthread_mutex_lock(&mutex);
copyblock tmp=*((copyblock*)arg);
lseek(tmp.sfd,tmp.start,SEEK_SET);
lseek(tmp.dfd,tmp.start,SEEK_SET);
char buf[BLOCKSIZE+1];
int readsize;
int writesize;
if (tmp.end>0)
{
memset(buf,0,sizeof(buf));
readsize=read(tmp.sfd,buf,sizeof(buf)-1);
writesize=write(tmp.dfd,buf,strlen(buf));
printf("%d,%d\n",readsize,writesize);
}
pthread_mutex_unlock(&mutex);
}
void copy()
{
printf("please input copy file name:");
char name[20];
memset(name,0,sizeof(name));
gets(name);
int sfd=open(name,O_RDONLY);
if (sfd==-1)
{
printf("open filefail \n");
}
char filename[10];
printf("plese input create file name:");
memset(filename,0,sizeof(filename));
gets(filename);
//printf("%s\n",filename);
int dfd=open(filename,O_CREAT|O_WRONLY,0777);
if (dfd==-1)
{
printf("create file fail \n");
}
struct stat st;
fstat(sfd,&st);
int filesize=st.st_size;
printf("size=%d\n",filesize);
const int n=filesize/BLOCKSIZE+1;
printf("n=%d\n",n);
copyblock cb[n];
int i;
for (i=0 ;i<n ;i++ )
{
cb[i].sfd=sfd;
cb[i].dfd=dfd;
cb[i].start=i*BLOCKSIZE;
cb[i].end=BLOCKSIZE;
if(i==n-1)
{
cb[i].end=filesize%BLOCKSIZE;
}
}
pthread_t th[n];
for(i=0;i<n;i++)
{
pthread_create(&th[i],NULL,(void*)copyfile,(void*)&cb[i]);
}
for(i=0;i<n;i++)
{
pthread_join(th[i],NULL);
}
pthread_exit(0);
}
void* taskwork(void *arg)
{
printf("%u doing \n",pthread_self());
pthread_t t1;
pthread_create(&t1,NULL,(void*)copy,NULL);
pthread_join(t1,NULL);
}
int main(int argc, char *argv[])
{
init_pool(3);
int i;
for(i=0;i<4;i++)
{
init_task(*taskwork,NULL);
}
while(1)
{
if(pool->worknum==0)
break;
}
pool_destroy();
return 0;
}
//利用线程池实现文件复制(一个文件)
//利用线程池实现文件复制(多文件),在每个子线程中创建线程实现分块复制