導航:首頁 > 源碼編譯 > 多線程演算法視頻

多線程演算法視頻

發布時間:2022-09-26 07:43:41

Ⅰ C#如何使用多線程做任務 但是做的是同一個任務 要求不能夠做重復的!! 這個要怎麼實現的

首先你需要將你的任務A拆分成N份(Yn),然後創建N個線程去處理Yn,最後將結果進行匯總計算。
例:
使用多線程處理1000W條數據,按照一定演算法計算著1000W條數據的結果值。
根據我CPU的特性(4核8線程),我打算創建8個線程來處理。
將1000W數據分成8份,讓每個線程單獨處理1份數據,將結果保存。
當8個線程處理完畢後,對8個結果進行處理,得出最終結果值。

Ⅱ 演算法和多線程哪個快為何

梨子和蘋果哪個壓稱?

java多線程: 如何阻塞和繼續線程運行 (轉)

典型地,suspend() 和 resume() 被用在等待另一個線程產生的結果的情形:測試發現結果還沒有產生後,讓線程阻塞,另一個線程產生了結果後,調用 resume() 使其恢復。但suspend()方法很容易引起死鎖問題,已經不推薦使用了。wait() 和 notify() 方法:兩個方法配套使用,wait() 使得線程進入阻塞狀態,它有兩種形式,一種允許 指定以毫秒為單位的一段時間作為參數,另一種沒有參數,前者當對應的 notify() 被調用或者超出指定時間時線程重新進入可執行狀態,後者則必須對應的 notify() 被調用。 初看起來它們與 suspend() 和 resume() 方法對沒有什麼分別,但是事實上它們是截然不同的。區別的核心在於,前面敘述的所有方法,阻塞時都不會釋放佔用的鎖(如果佔用了的話),而這一對方法則相反。 上述的核心區別導致了一系列的細節上的區別。 首先,前面敘述的所有方法都隸屬於 Thread 類,但是這一對卻直接隸屬於 Object 類,也就是說,所有對象都擁有這一對方法。初看起來這十分不可思議,但是實際上卻是很自然的,因為這一對方法阻塞時要釋放佔用的鎖,而鎖是任何對象都具有的,調用任意對象的 wait() 方法導致線程阻塞,並且該對象上的鎖被釋放。而調用 任意對象的notify()方法則導致因調用該對象的 wait() 方法而阻塞的線程中隨機選擇的一個解除阻塞(但要等到獲得鎖後才真正可執行)。 其次,前面敘述的所有方法都可在任何位置調用,但是這一對方法卻必須在 synchronized 方法或塊中調用,理由也很簡單,只有在 synchronized 方法或塊中當前線程才佔有鎖,才有鎖可以釋放。同樣的道理,調用這一對方法的對象上的鎖必須為當前線程所擁有,這樣才有鎖可以釋放。因此,這一對方法調用必須放置在這樣的 synchronized 方法或塊中,該方法或塊的上鎖對象就是調用這一對方法的對象。若不滿足這一條件,則程序雖然仍能編譯,但在運行時會出現IllegalMonitorStateException 異常。 wait() 和 notify() 方法的上述特性決定了它們經常和synchronized 方法或塊一起使用,將它們和操作系統的進程間通信機製作一個比較就會發現它們的相似性:synchronized方法或塊提供了類似於操作系統原語的功能,它們的執行不會受到多線程機制的干擾,而這一對方法則相當於 block 和wakeup 原語(這一對方法均聲明為 synchronized)。它們的結合使得我們可以實現操作系統上一系列精妙的進程間通信的演算法(如信號量演算法),並用於解決各種復雜的線程間通信問題。 關於 wait() 和 notify() 方法最後再說明兩點: 第一:調用 notify() 方法導致解除阻塞的線程是從因調用該對象的 wait() 方法而阻塞的線程中隨機選取的,我們無法預料哪一個線程將會被選擇,所以編程時要特別小心,避免因這種不確定性而產生問題。 第二:除了 notify(),還有一個方法 notifyAll() 也可起到類似作用,唯一的區別在於,調用 notifyAll() 方法將把因調用該對象的 wait() 方法而阻塞的所有線程一次性全部解除阻塞。當然,只有獲得鎖的那一個線程才能進入可執行狀態。 談到阻塞,就不能不談一談死鎖,略一分析就能發現,suspend() 方法和不指定超時期限的 wait() 方法的調用都可能產生死鎖。遺憾的是,Java 並不在語言級別上支持死鎖的避免,我們在編程中必須小心地避免死鎖。 以上我們對 Java 中實現線程阻塞的各種方法作了一番分析,我們重點分析了 wait() 和 notify() 方法,因為它們的功能最強大,使用也最靈活,但是這也導致了它們的效率較低,較容易出錯。實際使用中我們應該靈活使用各種方法,以便更好地達到我們的目的。

Ⅳ C++多線程的臨界區如何使用

從臨界區使用上講嵌套本身沒有問題,函數直接調用應該發生在同一個線程內,同一個線程內部重復進入是沒有阻塞問題的
但是這個問題隱含的邏輯是有重大意義的.在多線程條件下,演算法的設計並不能隨意進行,如果f1/f2不是函數調用而是跨線程使用,你首先要考慮這種嵌套使用的設計是否合理,而不是在不改變這種嵌套方式下尋求解決,很多時候這個是無解的.多線程設計演算法往往需要設計師首先考慮調整演算法避免出現你這種情況

python實現簡單多線程任務隊列

Python實現簡單多線程任務隊列
最近我在用梯度下降演算法繪制神經網路的數據時,遇到了一些演算法性能的問題。梯度下降演算法的代碼如下(偽代碼):
defgradient_descent(): # the gradient descent code plotly.write(X, Y)
一般來說,當網路請求 plot.ly 繪圖時會阻塞等待返回,於是也會影響到其他的梯度下降函數的執行速度。
一種解決辦法是每調用一次 plotly.write 函數就開啟一個新的線程,但是這種方法感覺不是很好。 我不想用一個像 cerely(一種分布式任務隊列)一樣大而全的任務隊列框架,因為框架對於我的這點需求來說太重了,並且我的繪圖也並不需要 redis 來持久化數據。
那用什麼辦法解決呢?我在 python 中寫了一個很小的任務隊列,它可以在一個單獨的線程中調用 plotly.write函數。下面是程序代碼。
classTaskQueue(Queue.Queue):
首先我們繼承 Queue.Queue 類。從 Queue.Queue 類可以繼承 get 和 put 方法,以及隊列的行為。
def__init__(self, num_workers=1): Queue.Queue.__init__(self) self.num_workers=num_workers self.start_workers()
初始化的時候,我們可以不用考慮工作線程的數量。
defadd_task(self, task,*args,**kwargs): args=argsor() kwargs=kwargsor{} self.put((task, args, kwargs))
我們把 task, args, kwargs 以元組的形式存儲在隊列中。*args 可以傳遞數量不等的參數,**kwargs 可以傳遞命名參數。
defstart_workers(self): foriinrange(self.num_workers): t=Thread(target=self.worker) t.daemon=True t.start()
我們為每個 worker 創建一個線程,然後在後台刪除。
下面是 worker 函數的代碼:
defworker(self): whileTrue: tupl=self.get() item, args, kwargs=self.get() item(*args,**kwargs) self.task_done()
worker 函數獲取隊列頂端的任務,並根據輸入參數運行,除此之外,沒有其他的功能。下面是隊列的代碼:
我們可以通過下面的代碼測試:
defblokkah(*args,**kwargs): time.sleep(5) print「Blokkah mofo!」 q=TaskQueue(num_workers=5) foriteminrange(1): q.add_task(blokkah) q.join()# wait for all the tasks to finish. print「Alldone!」
Blokkah 是我們要做的任務名稱。隊列已經緩存在內存中,並且沒有執行很多任務。下面的步驟是把主隊列當做單獨的進程來運行,這樣主程序退出以及執行資料庫持久化時,隊列任務不會停止運行。但是這個例子很好地展示了如何從一個很簡單的小任務寫成像工作隊列這樣復雜的程序。
defgradient_descent(): # the gradient descent code queue.add_task(plotly.write, x=X, y=Y)
修改之後,我的梯度下降演算法工作效率似乎更高了。如果你很感興趣的話,可以參考下面的代碼。 classTaskQueue(Queue.Queue): def__init__(self, num_workers=1):Queue.Queue.__init__(self)self.num_workers=num_workersself.start_workers() defadd_task(self, task,*args,**kwargs):args=argsor()kwargs=kwargsor{}self.put((task, args, kwargs)) defstart_workers(self):foriinrange(self.num_workers):t=Thread(target=self.worker)t.daemon=Truet.start() defworker(self):whileTrue:tupl=self.get()item, args, kwargs=self.get()item(*args,**kwargs)self.task_done() deftests():defblokkah(*args,**kwargs):time.sleep(5)print"Blokkah mofo!" q=TaskQueue(num_workers=5) foriteminrange(10):q.add_task(blokkah) q.join()# block until all tasks are doneprint"All done!" if__name__=="__main__":tests()

Ⅵ 串列的演算法 能用多線程嗎

串列的演算法能用多線程。
在任務量不大的時候,串列化比多線程更快,在任務量大的時候多線程才比較有用。
正常情況下,用串列化就可以了,因為如果用多線程的話,它的優勢不會顯現出來,而且還比較浪費。

Ⅶ JAVA中實現多線程負載平衡演算法

將請求放到一個全局的隊列中去。每個子線程不斷地從隊列中取出請求並處理請求,如果隊列中沒有請求則子線程等待。

Ⅷ c++非阻塞多線程實例應用的演算法有哪些

多線程非阻塞模式到現在算是告一段落吧 雖然還有一些小的bug需要修正 總結一下 准備向後面進發


實現功能: 本程序主要實現遠程計算的功能 通過非阻塞套接字和多線程的結合 讓通信變得高效 伺服器通過維護一個客戶端鏈表來實現對多個客戶響應 客戶端自身驗證表達式的正確性 當輸入Byebye時 伺服器回復OK 此時客戶端斷開連接退出

總結:

不管用何種方式通信 相關聯的幾個線程總會用一個變數來控制所有的其他線程

對於非阻塞套接字 Recv Send Connect Accept等都需要套上一個基於共同控制變數或者永真的循環來實現對WSAEWOULDBLOCK的返回重試

對於通過事件信號量來通知的兩個線程 例如生產者 消費者(生產者生產好了通過hEvent通知消費者) 當生產者退出時 一定要通過該信號量來通知消費者 以免消費者阻塞於WaitForSingleObject 而消費者在等到信號量時 也一定要檢測生產者是否已經退出(或者是說在這里的斷開了連接) 以免發送或接收未知的數據

對於有信號量控制的兩個同步線程 要注意是否有共同訪問的數據 要時刻記得對數據進行互斥訪問

Ⅸ java中多線程如何互相操作

Java線程:線程的交互

SCJP5學習筆記

線程交互是比較復雜的問題,SCJP要求不很基礎:給定一個場景,編寫代碼來恰當使用等待、通知和通知所有線程。

一、線程交互的基礎知識

SCJP所要求的線程交互知識點需要從java.lang.Object的類的三個方法來學習:

void notify()
喚醒在此對象監視器上等待的單個線程。
void notifyAll()
喚醒在此對象監視器上等待的所有線程。
void wait()
導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法。

當然,wait()還有另外兩個重載方法:
void wait(long timeout)
導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量。
void wait(long timeout, int nanos)
導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量。

以上這些方法是幫助線程傳遞線程關心的時間狀態。

關於等待/通知,要記住的關鍵點是:
必須從同步環境內調用wait()、notify()、notifyAll()方法。線程不能調用對象上等待或通知的方法,除非它擁有那個對象的鎖。
wait()、notify()、notifyAll()都是Object的實例方法。與每個對象具有鎖一樣,每個對象可以有一個線程列表,他們等待來自該信號(通知)。線程通過執行對象上的wait()方法獲得這個等待列表。從那時候起,它不再執行任何其他指令,直到調用對象的notify()方法為止。如果多個線程在同一個對象上等待,則將只選擇一個線程(不保證以何種順序)繼續執行。如果沒有線程等待,則不採取任何特殊操作。

下面看個例子就明白了:
/**
* 計算輸出其他線程鎖計算的數據
*
* @author leimin 2008-9-15 13:20:38
*/
public class ThreadA {
public static void main(String[] args) {
ThreadB b = new ThreadB();
//啟動計算線程
b.start();
//線程A擁有b對象上的鎖。線程為了調用wait()或notify()方法,該線程必須是那個對象鎖的擁有者
synchronized (b) {
try {
System.out.println("等待對象b完成計算。。。");
//當前線程A等待
b.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("b對象計算的總和是:" + b.total);
}
}
}

/**
* 計算1+2+3 ... +100的和
*
* @author leimin 2008-9-15 13:20:49
*/
public class ThreadB extends Thread {
int total;

public void run() {
synchronized (this) {
for (int i = 0; i < 101; i++) {
total += i;
}
//(完成計算了)喚醒在此對象監視器上等待的單個線程,在本例中線程A被喚醒
notify();
}
}
}

等待對象b完成計算。。。
b對象計算的總和是:5050

Process finished with exit code 0

千萬注意:
當在對象上調用wait()方法時,執行該代碼的線程立即放棄它在對象上的鎖。然而調用notify()時,並不意味著這時線程會放棄其鎖。如果線程榮然在完成同步代碼,則線程在移出之前不會放棄鎖。因此,只要調用notify()並不意味著這時該鎖變得可用。

二、多個線程在等待一個對象鎖時候使用notifyAll()

在多數情況下,最好通知等待某個對象的所有線程。如果這樣做,可以在對象上使用notifyAll()讓所有在此對象上等待的線程沖出等待區,返回到可運行狀態。

下面給個例子:
/**
* 計算線程
*
* @author leimin 2008-9-20 11:15:46
*/
public class Calculator extends Thread {
int total;

public void run() {
synchronized (this) {
for (int i = 0; i < 101; i++) {
total += i;
}
}
//通知所有在此對象上等待的線程
notifyAll();
}
}

/**
* 獲取計算結果並輸出
*
* @author leimin 2008-9-20 11:15:22
*/
public class ReaderResult extends Thread {
Calculator c;

public ReaderResult(Calculator c) {
this.c = c;
}

public void run() {
synchronized (c) {
try {
System.out.println(Thread.currentThread() + "等待計算結果。。。");
c.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "計算結果為:" + c.total);
}
}

public static void main(String[] args) {
Calculator calculator = new Calculator();

//啟動三個線程,分別獲取計算結果
new ReaderResult(calculator).start();
new ReaderResult(calculator).start();
new ReaderResult(calculator).start();
//啟動計算線程
calculator.start();
}
}

運行結果:
Thread[Thread-1,5,main]等待計算結果。。。
Thread[Thread-2,5,main]等待計算結果。。。
Thread[Thread-3,5,main]等待計算結果。。。
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.notifyAll(Native Method)
at threadtest.Calculator.run(Calculator.java:18)
Thread[Thread-1,5,main]計算結果為:5050
Thread[Thread-2,5,main]計算結果為:5050
Thread[Thread-3,5,main]計算結果為:5050

Process finished with exit code 0

運行結果表明,程序中有異常,並且多次運行結果可能有多種輸出結果。這就是說明,這個多線程的交互程序還存在問題。究竟是出了什麼問題,需要深入的分析和思考,下面將做具體分析。

實際上,上面這個代碼中,我們期望的是讀取結果的線程在計算線程調用notifyAll()之前等待即可。 但是,如果計算線程先執行,並在讀取結果線程等待之前調用了notify()方法,那麼又會發生什麼呢?這種情況是可能發生的。因為無法保證線程的不同部分將按照什麼順序來執行。幸運的是當讀取線程運行時,它只能馬上進入等待狀態----它沒有做任何事情來檢查等待的事件是否已經發生。 ----因此,如果計算線程已經調用了notifyAll()方法,那麼它就不會再次調用notifyAll(),----並且等待的讀取線程將永遠保持等待。這當然是開發者所不願意看到的問題。

因此,當等待的事件發生時,需要能夠檢查notifyAll()通知事件是否已經發生。

通常,解決上面問題的最佳方式是將

×××××××××××××××××××××××××××××
以上來自http://lavasoft.blog.51cto.com/62575/99157
這是一個系列線程的問題。。舉例簡單,但是很實用

閱讀全文

與多線程演算法視頻相關的資料

熱點內容
交換老婆系列小說 瀏覽:276
支持投屏的在線影院 瀏覽:842
男主是鴨子公關 瀏覽:59
yy680 瀏覽:785
二戰德國納粹電影 瀏覽:500
雲存儲搭建伺服器 瀏覽:849
被禁的40部小說有哪些 瀏覽:245
通吃小子好小子小傑 瀏覽:42
肉多的霸總文 瀏覽:943
可以投屏的電影網站 瀏覽:400
黃有聲故事 瀏覽:484
重生末世之塵華 瀏覽:746
優化演算法的輸入維數越不容易收斂 瀏覽:777
java極限編程pdf 瀏覽:130
塞葡萄的是哪個小說 瀏覽:821
架設傳奇命令 瀏覽:953
關於醫生的小說 瀏覽:520
愛情動作電影 瀏覽:808
八零電子書txt免費下載網站 瀏覽:509
登陸遼事通顯示伺服器連接錯誤怎麼辦 瀏覽:547