zoukankan      html  css  js  c++  java
  • 1.10 编程之美-双线程下载[double threads to download]

    【本文链接】

    http://www.cnblogs.com/hellogiser/p/double-threads-to-download-and-write.html

    【题目】

            网络上下载数据,然后存储到硬盘上。简单做法是:先下载一块然后写到硬盘,然后再下载,再写到硬盘上。

            缺点:需要先下载完才能写入硬盘,下载和写是串行操作。

            改进:让两个线程并行进行,设置缓冲区,采用信号量的形式。

                        下载线程,只要缓冲区有空余就下载,下载完成之后告诉写线程缓冲区有数据了。

                         写线程,只要缓冲区有数据就写入,写完后告诉下载线程缓冲区有空闲了。

    【代码】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     
    //
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/7/4
    */

    //---------------------API------------------------------
    //downloads a block from Internet sequentially in each call
    //return true, if the entire file is downloaded, otherwise false.
    bool GetBlockFromNet(Block *out_block);

    //writes a block to hard disk
    bool WriteBlockToDisk(Block *in_block);

    class Thread
    {
    public:
        Thread(
    void (*work_func)());
        ~Thread();
        
    void Start();
        
    void Abort();
    };

    class Semaphore
    {
    public:
        Semaphore(
    int count, int max_count);
        ~Semaphore();
        
    void Unsignal();
        
    void Signal();
    };

    class Mutex
    {
    public:
        WaitMutex();
        ReleaseMutex();
    };
    //----------------------------------------------------


    //1.确定使用信号量,而非互斥量,保证并行操作
    //2.当缓冲区并不满并且下载没结束时,下载线程运行
    //3.当缓冲区并不空并且下载没结束时,存储线程运行


    #define MAX_COUNT 1000
    //缓冲区数组,模拟循环队列
    Block g_Buffer[MAX_COUNT];
    Thread g_Download(ProcA);
    Thread g_Write(ProcB);

    //一开始缓冲区空间为MAX_COUNT,整个缓冲区可供下载的数据填充
    Semaphore ForDownload(MAX_COUNT, MAX_COUNT);
    //一开始缓冲区无数据可供存储
    Semaphore ForWrite(0, MAX_COUNT);

    //下载任务是否完成
    bool isDone;
    //下载的数据从缓冲区的哪个地方开始填充
    int in_index;
    //存储的数据从缓冲区的哪个地方开始提取
    int out_index;

    void ProcA()
    {
        
    while(true)
        {
            
    //首先取得一个空闲空间,以便下载数据填充
            ForDownload.Unsignal();
            
    //填充
            isDone = GetBlockFromNet(g_Buffer + in_index);
            
    //更新索引
            in_index = (in_index + 1) % MAX_COUNT;
            
    //提示存储线程可以工作
            ForWrite.Signal();

            
    //当任务全部下载完成,进程就可以结束了
            if(isDone)
                
    break;
        }
    }

    void ProcB()
    {
        
    while(true)
        {
            
    //查询时候有数据可供存储
            ForWrite.Unsignal();
            
    //存储
            WriteBlockToDisk(g_Buffer + out_index);
            
    //更新索引
            out_index = (out_index + 1) % MAX_COUNT;
            
    //将空闲空间还给缓冲区
            ForDownload.Signal();

            
    //当任务全部下载完成,并且所有的数据都存储到硬盘中,进程才可以结束
            if(isDone && in_index == out_index)
                
    break;
        }
    }

    int main()
    {
        isDone = 
    false;
        in_index = 
    0;
        out_index = 
    0;
        g_Download.Start();
        g_Write.Start();
    }

    【参考】

    http://www.cnblogs.com/daniagger/archive/2012/03/23/2413764.html

    http://www.cnblogs.com/youxin/p/3586975.html

    http://blog.csdn.net/tianshuai1111/article/details/7692213

    【本文链接】

    http://www.cnblogs.com/hellogiser/p/double-threads-to-download-and-write.html

    个人学习笔记,欢迎拍砖!---by hellogiser

    Author: hellogiser
    Warning: 本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,且在文章页面明显位置给出原文连接。Thanks!
    Me: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    XNA中的中文输入(三)
    0.033秒的艺术 测试程序性能
    0.033秒的艺术 List.Sort以及快速排序
    从Demo到Engine(二) Render Queue Sort
    Bounding Volume Performance Test:AABB vs OBB vs Sphere
    0.033秒的艺术 Radix Sort
    从Demo到Engine(一) IRenderable
    0.033秒的艺术 for vs. foreach
    XNA中的中文输入(一)
    0.033秒的艺术 XNA数学库中的陷阱
  • 原文地址:https://www.cnblogs.com/hellogiser/p/double-threads-to-download-and-write.html
Copyright © 2011-2022 走看看