迅雷下载原理的源代码(linux c)

这是一个使用C语言在Linux环境下实现的线程池文件复制程序,模仿迅雷下载原理,通过多线程分块复制文件。程序包括线程池的初始化、任务调度、文件复制及线程池销毁等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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;
}

//利用线程池实现文件复制(一个文件)
//利用线程池实现文件复制(多文件),在每个子线程中创建线程实现分块复制


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值