雙執行緒高效下載問題
一.問題描述和分析
問題描述:
雙執行緒高效下載的過程為:程式不斷的從網路中讀取資料,寫到緩衝區(即記憶體)中,然後再從緩衝區寫到磁碟中。這是一個序列執行的過程。
分析:
生產者-消費者問題的思想為:生產者不斷地往緩衝區生產資料,消費者不斷從緩衝區中消費資料。
該問題符合用生產者-消費者問題,程式的一部分功能負責從網路讀取資料,寫到緩衝區中,該為生產者;程式的另一部分功能負責從緩衝區讀取資料,寫道本地磁碟中,該為消費者。
我們可以將這兩部分序列的功能,通過兩個執行緒實現並行化,一個執行緒實現生產者的功能,另一個執行緒實現消費者的功能。這裡還需要設定兩個訊號量:一個“空訊號量,即該位置為空”的訊號量;一個“滿訊號量,即該位置已有資料”的訊號量。
二.虛擬碼實現如下:
類的宣告如下:
//類的宣告如下 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