Rust多線程計算一定范圍內(nèi)的質(zhì)數(shù)

背景引入
學(xué)數(shù)學(xué)學(xué)累了放松一下,學(xué)一會兒rust,今天是學(xué)習(xí)rust的第一天。
計算質(zhì)數(shù)是學(xué)習(xí)編程入門的案例,也可能是初學(xué)者的噩夢。但是時間長了之后就習(xí)慣了。
比如打印1~1000以內(nèi)的質(zhì)數(shù),或者范圍更大。打印所有的質(zhì)數(shù)、輸出質(zhì)數(shù)有多少個
這里我們可以嘗試用多線程的方式,將一個大范圍分成很多個小范圍,然后用多線程的方式來計算。
rust語言也是一個性能非常高的語言,性能和效率僅次于C語言。同時也有很好的并發(fā)性能。然而python不適合寫cpu密集型的程序,所以這里嘗試一下Rust語言。
開始代碼
執(zhí)行以下python代碼可知,0~2000的質(zhì)數(shù)有303個
注:檢測質(zhì)數(shù)其實可以寫成O(?N)的。這里直接寫的是O(N)復(fù)雜度的代碼。
開始Rust語言,可以把范圍分成兩段,0~999 ?和 ?1000~1999
關(guān)鍵是線程函數(shù)沒法帶參數(shù),這太惡心了。導(dǎo)致我分成兩個范圍代碼重復(fù)嚴(yán)重。
但是函數(shù)可以套函數(shù),這太好了。
先把上面的代碼用匿名函數(shù)改成這樣
join 方法可以使子線程運行結(jié)束后再停止運行程序。
然后再把兩個函數(shù)合并寫成一個,但是這里就出問題了,匿名函數(shù)里訪問了外部的t變量和rangelen變量。
引用菜鳥教程的話
在子線程中嘗試使用當(dāng)前函數(shù)的資源,這一定是錯誤的!因為所有權(quán)機制禁止這種危險情況的產(chǎn)生,它將破壞所有權(quán)機制銷毀資源的一定性。我們可以使用閉包的 move 關(guān)鍵字來處理:
這樣發(fā)現(xiàn)就好了,打印了303行。
接下來就可以加大數(shù)據(jù)量測試了。
打印了1229行。說明一萬以內(nèi)有1229個質(zhì)數(shù),經(jīng)過相同算法邏輯的單線程python代碼驗證正確。
以下是繼續(xù)優(yōu)化了一下代碼
現(xiàn)在又出現(xiàn)一個問題,打印太多行了,不方便統(tǒng)計,還得整體復(fù)制到txt里看看有多少行,應(yīng)該添加一個cout變量記錄有多少個質(zhì)數(shù),然后把拖慢速度的print去掉。
上述方法肯定是不行的,這里應(yīng)該是涉及到了多個線程對外部變量進行修改的問題,而且還涉及到了閉包和變量的問題。
經(jīng)過了一番大力的搜索,看案例學(xué)習(xí)了一下線程通信問題的問題,現(xiàn)在居然又有新的bug產(chǎn)生了,10個管道傳送完了所有的數(shù)據(jù)之后居然還在等待。接收端的for循環(huán)沒有結(jié)束。
問題應(yīng)該是這樣的,我創(chuàng)建了一個管道,然而我克隆了10個管道,我的10個子線程都用完了10個管道之后把這些管道都關(guān)閉了,然而還有那個主管道其實一直沒有被我用。主管道的接收端就會一直在等待。
一邊搜一邊做的,搜不到rust的多線程計算質(zhì)數(shù),只能一點點摸著石頭過河,只搜到了java的,變量所有權(quán)的東西還沒有掌握太好。擺爛了,先暫時先做成這樣。以后再優(yōu)化。