凯发真人娱乐

1.10 编程之美-凯发真人娱乐

2023-08-15,,

【本文链接】

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.当缓冲区并不空并且下载没结束时,存储线程运行

//缓冲区数组,模拟循环队列
block g_buffer[max_count];
thread g_download(proca);
thread g_write(procb);

//一开始缓冲区空间为max_count,整个缓冲区可供下载的数据填充
semaphore fordownload(max_count, max_count);
//一开始缓冲区无数据可供存储
, max_count);

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

void proca()
{
    while(true)
    {
        //首先取得一个空闲空间,以便下载数据填充
        fordownload.unsignal();
        //填充
        isdone = getblockfromnet(g_buffer   in_index);
        //更新索引
) % max_count;
        //提示存储线程可以工作
        forwrite.signal();

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

void procb()
{
    while(true)
    {
        //查询时候有数据可供存储
        forwrite.unsignal();
        //存储
        writeblocktodisk(g_buffer   out_index);
        //更新索引
) % max_count;
        //将空闲空间还给缓冲区
        fordownload.signal();

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

int main()
{
    isdone = false;
    in_index = ;
    out_index = ;
    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

1.10 -双线程下载[double threads to download]的相关教程结束。

网站地图