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

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



迅雷下载原理的源代码(linux c)相关推荐

  1. 迅雷下载原理及其协议分析

    迅雷下载原理及其协议分析 2012-08-26 迅雷是一个多协议的的P2SP下载管理器,除了支持基本的HTTP.FTP下载,还支持同一个资源的多种P2P协议下载,例如BT和电驴协议.当然,最大的特点是 ...

  2. [缓存]迅雷下载原理

    来自:http://hi.baidu.com/gcjia/blog/item/2b77bc3df8544803bba1675f.html 1.迅雷是什么? 迅雷是基于P2SP的一款下载软件,能够大大增 ...

  3. BT、电骡、迅雷等P2P下载原理

    迅雷的下载原理: 一.迅雷下载原理分析      迅雷的工作原理据称为"多资源超线程技术基于网格原理,能够将网络上存在的服务器和计算机资源进行有效的整合".实际上还是传统的下载技术 ...

  4. 迅雷下载Linux Oracle11gR2和Oracle12c

    很多朋友分享的都是百度云盘链接,那个下载速度对于贫民来说,真的是等到花都谢了 而Oracle官网现在只能下载Oracle19C了,特此分享11和12版本的迅雷下载链接 11g下载链接: https:/ ...

  5. 一文搞懂Linux系统内核升级及下载当前内核源代码

    1. 下载当前内核源代码 为什么下载内核源代? 一是便于查看或学习linux内核代码的底层实现方法: 二是便于编写或调试Linux设备驱动程序,因为驱动程序的编译需要内核源代码. 怎么下载? 如果你是 ...

  6. 迅雷高速下载免安装 Kali Linux

    Kali 介绍 Kali Linux 是一个高级渗透测试和安全审计 Linux 发行版.作为使用者,你可以把它理解成为一个特殊的Linux发行版,集成了精心挑选的渗透测试和安全审计的工具,供渗透测试和 ...

  7. [缓存]迅雷下载的原理——P2SP加速技术

    BT的出现使大多数人现在对P2P并不陌生,P2P的下载概念,简单点说,就是下载不再象传统方式那样只能依赖服务器,内容的传递可以在网络上的各个终端机器中进行. 而现在,P2SP出现使用户有了更好的选择, ...

  8. linux视频教程 迅雷下载地址,在linux中下载迅雷链接(thunder://)

    迅雷下载协议是经过加密的,如: thunder://QUFodHRwOi8vd3d3LmNub3N3aWtpLmNvbS93cC1jb250ZW50L3RoZW1lcy9tb25vY2hyb21lL2 ...

  9. 迅雷下载任务是dl2.php,xxqqweb 喜喜网络硬盘程序(集成迅雷下载版)是一个免费的文件存储 。 己 Web Server 263万源代码下载- www.pudn.com...

    文件名称: xxqqweb下载  收藏√  [ 5  4  3  2  1 ] 开发工具: HTML 文件大小: 171 KB 上传时间: 2016-09-09 下载次数: 0 提 供 者: igup ...

最新文章

  1. LeetCode实战:反转字符串
  2. CentOS安装编译环境
  3. springboot 配置多线程
  4. 阿里云HBase全新发布X-Pack NoSQL数据库再上新台阶 1
  5. java里面运行js_在java中利用rhino执行javascript
  6. 小龙多功能工具箱,邮件群发微信多开
  7. Nginx进程以及事件处理模型
  8. java ssh完整配置文件_ssh框架整合笔记---配置文件
  9. 职称计算机xp练习题,职称计算机考试模块WindowsXP练习题(1)
  10. sql server 2005学习笔记之触发器简介(一)
  11. mongo go 查询指定字段_使用PyMongo查询MongoDB数据库!
  12. 战舰少女服务器不显示,战舰少女进不去 闪退及连接不上解决方法
  13. 银河麒麟系统怎么安装微软雅黑字体
  14. oracle建表创建约束
  15. stm32 带通滤波器_【安富莱——DSP教程】第37章 FIR滤波器的实现
  16. ubuntu挂载windows分区
  17. (45.2)【端口漏洞发现】扫描工具Nmap、Nessus、Masscan、端口弱口令检查
  18. 猫有哪些比较常见的肢体语言?
  19. 【数据分析与挖掘(二)】面试题汇总(附答案)
  20. android如何设置自适应大小的背景图片,如何调整背景图片大小以适应Android中的应用程序屏幕大小...

热门文章

  1. systemctl 实现开机自启服务
  2. 对自己现阶段职业规划的一些思考
  3. NPC_3level_Inverter:基于MATLAB Simulink的中性点钳位三电平逆变器仿真模型
  4. 用AI算法起中文名字 ---- AI起名的评价
  5. Matlab来绘制三维曲面图、等高线图等
  6. 谷歌Shell脚本编程规范笔记
  7. 2020 Ansys Lumerical FDTD MODE安装步骤说明
  8. Scrapy爬取当当网图书销售前100
  9. 继续注册前请先阅读终极QQ数字点卡公司在线销售协议 一、新疆维吾尔自治区阿克苏地区终极QQ网络电子商务有限公司使用自己建设的代理商专用电子商务平台系统,通过国际互联网络为用户提供网络游戏分销服务。同
  10. 机器 · 搜索 · 未来