1. 程式人生 > >雙執行緒高效下載問題

雙執行緒高效下載問題

一.問題描述和分析

問題描述:

       雙執行緒高效下載的過程為:程式不斷的從網路中讀取資料,寫到緩衝區(即記憶體)中,然後再從緩衝區寫到磁碟中。這是一個序列執行的過程。

分析:

        生產者-消費者問題的思想為:生產者不斷地往緩衝區生產資料,消費者不斷從緩衝區中消費資料。

        該問題符合用生產者-消費者問題,程式的一部分功能負責從網路讀取資料,寫到緩衝區中,該為生產者;程式的另一部分功能負責從緩衝區讀取資料,寫道本地磁碟中,該為消費者。

       我們可以將這兩部分序列的功能,通過兩個執行緒實現並行化,一個執行緒實現生產者的功能,另一個執行緒實現消費者的功能。這裡還需要設定兩個訊號量:一個“空訊號量,即該位置為空”的訊號量;一個“滿訊號量,即該位置已有資料”的訊號量。


二.虛擬碼實現如下:

類的宣告如下:

//類的宣告如下
class Thread
{
public:
	Thread(void(*work_func)());  //該執行緒執行的函式為work_func
    ~Thread();
	void start(); //啟動執行緒
	void abort(); //終止執行緒
};

class Semaphore
{
public:
	Semaphore(int count,int max_count);//表示訊號量初始值為count,訊號量的最大值為max_count
    ~Semaphore();
	void Signal();  //count++  訊號量加一
	void Unsignal(); //count--  訊號量減一
};

class Mutex  //互斥鎖
{
public:
	WaitMutex(); //加鎖
    ReleaseMutex(); //解鎖
};

主函式實現如下:

#define BUFFER_COUNT 100  //定義緩衝區大小
Block g_buffer[BUFFER_COUNT]; //定義緩衝區
Thread g_threadA(PROCA); //定義執行緒A,其執行函式為PROCA
Thread g_threadB(PROCB); //定義執行緒B,其執行函式為PROCB

//由於緩衝區初始為空,所以滿訊號量g_seFull初始為0,空訊號量g_seEmpty初始為緩衝區大小BUFFER_COUNT
Semaphore g_seFull(0,BUFFER_COUNT); //定義訊號量g_seFull,初始值為0,最大為BUFFER_COUNT
Semaphore g_seEmpty(BUFFER_COUNT,BUFFER_COUNT);//定義訊號量g_seEmpty,其初始值為BUFFER_COUNT,最大值為BUFFER_COUNT

bool g_downloadComplete; //定義從網路下載是否完成

int in_index; //生產者的指標
int out_index; //消費者的指標

void main()
{
	g_downloadComplete = false;
	threadA.start();
	threadB.start();
}

//生產者,往緩衝區寫資料
void PROCA()
{
	while(true)
	{
		g_seEmpty.Unsignal();//消費掉一個空區域,g_seEmpty訊號量減一
		g_downloadComplete = GetBlockFromNet(g_buffer + in_index); //從網路讀取資料,並存放到緩衝區中
		in_index = (in_index + 1) % BUFFER_COUNT;  
		g_seFull.Signal();  //生產一個滿區域,g_seFull訊號量加一
		if(g_downloadComplete) break;
	}
}

//消費者,從緩衝區取資料
void PROCB()
{
	while(true)
	{
		g_seFull.Unsignal();  //消費掉一個滿區域,g_seFull訊號量減一
		WriteBlockToDisk(g_buffer + out_index);
		out_index  = (out_index + 1) % BUFFER_COUNT;
		g_seEmpty.Sigal();  //生產一個空區域,g_seEmpty訊號量加一
        if(g_downloadComplete && out_index == in_index)  //下載完成,並且緩衝區已為空,則推出
			break;
	}
}

三.總結

       如果一個程式是由K個序列的動作執行的,可以將這k個動作並行做,一個執行緒負責一個動作,以此實現多執行緒。



相關推薦

執行高效下載問題

一.問題描述和分析 問題描述:        雙執行緒高效下載的過程為:程式不斷的從網路中讀取資料,寫到緩衝區(即記憶體)中,然後再從緩衝區寫到磁碟中。這是一個序列執行的過程。 分析:         生產者-消費者問題的思想為:生產者不斷地往緩衝區生產資料,消費者不斷從緩

android多執行斷點下載

多執行緒斷電xia下載,通過設定執行緒的數量,動態獲取下載檔案執行緒的個數,這是本人用於練習所寫demo,註釋很詳細,用於初學者參考使用。 MainActivity.java頁面   package com.dahui.download; import java.io.Buf

執行讀寫佇列資料

MFC對話方塊中一個按鈕的響應函式實現兩個功能: 顯示資料同時處理資料,因此開兩個執行緒,一個執行緒顯示資料(開了一個定時器,響應WM_TIMER訊息按照一定時間間隔向TeeChart圖表新增資料並顯示)同時在佇列隊尾新增資料,另一個執行緒從該佇列隊頭去資料來處理。 下面就來解決這個案例。先來分

Java 多執行分段下載原理分析和實現

多執行緒下載介紹   多執行緒下載技術是很常見的一種下載方案,這種方式充分利用了多執行緒的優勢,在同一時間段內通過多個執行緒發起下載請求,將需要下載的資料分割成多個部分,每一個執行緒只負責下載其中一個部分,然後將下載後的資料組裝成完整的資料檔案,這樣便大大加快了下載效率。常見的下載器,迅

ios開發網路-大檔案的多執行斷點下載

說明:本文介紹多執行緒斷點續傳。專案中使用了蘋果自帶的類,實現了同時開啟多條執行緒下載一個較大的檔案。 因為實現過程較為複雜, 實現思路:下載 開始,建立一個與要下載檔案大小相同的檔案(如果要下載100M,那麼就在沙盒建立一個100M的檔案,然後計算每一段的下載量,開啟多條執行緒下載各段的資料,分

android多執行暫停下載-HttpURLConnection

android多執行緒暫停下載-HttpURLConnection private EditText et_path; private LinearLayout ll_pbs; @Override protected void onCreate(Bundle sa

從CSV檔案中讀取jpg圖片的URL地址並多執行批量下載

很多時候,我們的網站上傳圖片時並沒有根據內容進行資料夾分類,甚至會直接儲存到阿里雲的OSS或是七牛雲等雲端儲存上。這樣,當我們需要打包圖片時,就需要從資料庫找尋分類圖片,通過CURL進行下載。我最近剛剛完成了一個這樣的任務,覺得會比較常用,就把程式放到了github上分享給大家,希望大家能夠喜歡。 do

執行斷點下載工具

多執行緒斷點下載工具需要完成以下幾個功能:         * 1.通過提供的網路檔案地址,下載該檔案         * 2.要求使用多個執行緒同時下載,並且實時更新下載進度(0%~100%)  &n

java 使用RandomAssessFile類多執行切片下載檔案之伺服器如何實現

因為之前寫的都是客戶端,不需要去管服務端,直接把檔案放伺服器裡面,直接訪問,伺服器(tomcat之類得)就會自動幫我們切片,之類的。然後我自己想測試一些直接訪問檔案和使用控制器io讀寫返回檔案哪個快一些(肯定是io)https://blog.csdn.net/yali_a

redis單執行處理,以及單執行的優缺點

Redis快的主要原因是: 完全基於記憶體 資料結構簡單,對資料操作也簡單 使用多路 I/O 複用模型 單程序單執行緒好處 程式碼更清晰,處理邏輯更簡單 不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導致的效能消耗 不存在

OkHttp實現多執行併發下載的筆記

         打個廣告,不瞭解OkHttp的話可以先看下  http://blog.csdn.net/brycegao321/article/details/51830525             需求:  手機拍攝若干張照片, 在wifi連線下上傳到伺服器。  

IOS網路、多執行、shareSDK-使用EDG多執行技術下載圖片

使用EDG中央排程多執行緒技術實現圖片的非同步下載 // //  ViewController.swift //  Dome2test // //  Created by 郭文亮 on 2018/11

java 多執行批量下載美女圖片

今天無聊想寫個java程式,就寫了個下載圖片的程式,從 www.meizitu.com批量下載圖片 package test; import java.io.File; import java.io.FileOutputStream; import java.io.IOE

Android 執行池模擬多執行併發下載任務

廢話不多,直接上原始碼 自定義一個Adapter public class MyAdapter extends BaseAdapter { private Context context; private List<Progress> list

D 探 尋 寶 藏(執行DP)

題目連結:D 探 尋 寶 藏 D 探 尋 寶 藏 記憶體限制:64MB 時間限制:1s Special Judge: No 題目描述: 傳說HMH大沙漠中有一個M*N迷宮,裡面藏有許多寶物。某天,Dr.Kong找到了迷宮的地圖,他發現迷宮內處處有寶物,最

執行 線性dp 傳紙條

/* 兩種做法:一是暴力dp[i][j][k][l] 二是以走的步數k作為階段, dp[k][i][j]表示走到第k步,第一個人橫座標走到i,第二個人橫座標走到j 可以以此推出第第一個人的座標為[i,k-i+1],第二個人座標[j,k-j+1] 狀態轉移方程 dp[k][i][j]=max(dp[

NYOJ 61 傳紙條(一)(執行dp)

傳紙條(一) 時間限制:2000 ms  |  記憶體限制:65535 KB 難度:5 描述 小淵和小軒是好朋友也是同班同學,他們在一起總有談不完的話題。一次素質拓展活動中,班上同學安排做

Java 大文字多執行高效讀取

本文介紹 Java多執行緒讀取大檔案效能提升的高效方案。 前沿 我們在讀取一個正常檔案的時候,將使用,BufferedReader.read() 的三種方法: BufferedReader.read()  單位元組,這個效率最低,基本不考了 BufferedReader.

使用jetty做為server提供多執行檔案下載

背景   最近在做的一個專案,兩個java程序之間會涉及一個大資料量的傳遞過程,基本都是圖片檔案,(做了壓縮後還是會比較大,最大的有超過600MB)。其次這兩個java程序是在跨機房,比如中國和美國機房,網路待框也就幾百kB。   這就是本文的專案背景 分析 1.  600MB的檔案,都是A程序執行

執行--改變事件訊號有無,協調工作

#include "stdafx.h" #include "windows.h"#include "stdio.h" HANDLE g_hEvent = 0;//接收事件控制代碼 //子執行緒1 DWORD CALLBACK PrintProc(LPVOID pParam