其實最簡單的方法是用timer控件,timer控件本事就是對一個線程的封裝
創(chuàng)新互聯(lián)專注于中大型企業(yè)的網(wǎng)站設(shè)計、成都網(wǎng)站制作和網(wǎng)站改版、網(wǎng)站營銷服務(wù),追求商業(yè)策劃與數(shù)據(jù)分析、創(chuàng)意藝術(shù)與技術(shù)開發(fā)的融合,累計客戶1000多家,服務(wù)滿意度達97%。幫助廣大客戶順利對接上互聯(lián)網(wǎng)浪潮,準確優(yōu)選出符合自己需要的互聯(lián)網(wǎng)運用,我們將一直專注成都品牌網(wǎng)站建設(shè)和互聯(lián)網(wǎng)程序開發(fā),在前進的路上,與客戶一起成長!
所以你用兩個timer控件就可以模擬兩個線程了
或者用兩個backgroundworker控件,這個更逼真,不用定時觸發(fā)
具體用法,我空間里有教程
希望能解決您的問題。
在PHP-FPM處理HTTP請求時,有時會遇到一個請求需要進行多次MySQL查詢(在報表類應(yīng)用中比較常見)。通常我們會以串行方式查詢:
$link?=?new?mysqli();
$rs1?=?$link-query('SELECT?*?FROM?table1');
while?($row?=?$rs1-fetch_row())?{?...?}
$rs2?=?$link-query('SELECT?*?FROM?table2');
while?($row?=?$rs2-fetch_row())?{?...?}
$rs3?=?$link-query('SELECT?*?FROM?table3');
while?($row?=?$rs3-fetch_row())?{?...?}
串行查詢方式有個缺點:在MySQL返回數(shù)據(jù)之前,PHP一直是處于空等的狀態(tài),不會繼續(xù)往后執(zhí)行。如果數(shù)據(jù)量大或者查詢復(fù)雜,MySQL響應(yīng)可能會比較慢,那么以串行方式查詢會有一些延遲。給用戶最直接的感受就是 Loading… 的圈圈一直打轉(zhuǎn)。
那么有什么辦法可以減少查詢MySQL的時間?用多進程并行查詢不行,因為PHP-FPM 中不允許用 pcntl_fork 一類的調(diào)用。
幸好還有 mysqlnd,mysqlnd提供了類似 stream_select 的機制(見 這篇文章) ,可以做到在單進程中對MySQL并行查詢。這主要運用了mysqli_poll 和 reap_async_query 兩個函數(shù)。
還是通過例子來介紹MySQL并行查詢的實施方法。假設(shè)要并行地向MySQL發(fā)出10個查詢,最基本的代碼應(yīng)該是這樣的:
1.??$links?=?[];
2.??for?($i?=?0;?$i?!==?10;?$i++)?{
3.??????$links[$i]?=?new?mysqli('127.0.0.1',?'user',?'password',?'db1');
4.??????$links[$i]-query('SELECT?SLEEP(1)',?MYSQLI_ASYNC);
5.??}
6.??$allResult?=?[];
7.??while?(!empty($links))?{
8.??????$reads?=?$links;
9.??????$errors?=?$reject?=?[];
10.?????if?(!mysqli_poll($reads,?$errors,?$reject,?null))?{
11.?????????continue;
12.?????}
13.?????foreach?($reads?as?$read)?{
14.?????????$idx?=?array_search($read,?$links,?true);
15.?????????$allResult[$idx]?=?[];
16.?????????$result?=?$read-reap_async_query();
17.?????????while?($row?=?$result-fetch_row())?{
18.?????????????$allResult[$idx][]?=?$row;
19.?????????}
20.?????????$read-close();
21.?????????unset($links[$idx]);
22.?????}
23.?}
解釋下這段代碼的含義:
2~5行,同時發(fā)起10個MySQL連接,并發(fā)出查詢
注意query() 的第二個參數(shù)帶上了 MYSQLI_ASYNC 表示非阻塞查詢
10行,使用mysqli_poll 輪詢10個連接的查詢有無返回
mysqli_poll 的第一個參數(shù)$reads是個數(shù)組,包含需要輪詢那些連接。mysqli_poll 執(zhí)行完后,會改寫$reads,改寫后$reads包含的是那些已經(jīng)有數(shù)據(jù)返回連接。
mysqli_poll的第四個參數(shù),控制的是輪詢的等待時間,單位是“秒”。如果像本例當中設(shè)置為null,那么mysqli_poll輪詢是阻塞的:只有監(jiān)聽的連接中,任意一個連接有數(shù)據(jù)返回了,mysqli_poll才會返回。如果等待時間設(shè)置為0,那么每次執(zhí)行mysqli_poll會立即返回,外層的while會頻繁循環(huán)。
第11~19行,遍歷已經(jīng)有數(shù)據(jù)返回的連接
reap_async_query和普通query一樣,返回的是mysqli_result,可以一行行fetch數(shù)據(jù)
20~21行,對于已經(jīng)獲得了數(shù)據(jù)的連接,下次mysqli_poll就不需要再輪詢這個連接了,所以關(guān)閉連接,并從$links數(shù)組刪除這個連接
當所有的連接都返回了數(shù)據(jù),$links數(shù)組空了,while循環(huán)也就終止了。
使用并行查詢的方式,可以大大縮短處理HTTP請求的時間,假設(shè)本例中的10個SQL查詢,每個需要執(zhí)行1秒。因為是并行,處理所有的查詢,也只需要1秒左右。
Coordinator 線程負責判斷事務(wù)是否可以并行執(zhí)行,如果可以并行就把事務(wù)分發(fā)給 WorkThread 線程執(zhí)行,如果判斷不能執(zhí)行,如 DDL , 跨庫操作 等,就等待所有的worker線程執(zhí)行完成之后,再由 Coordinator 執(zhí)行。
一組事務(wù)同時提交也就意味著組內(nèi)事務(wù)不存在沖突,故組內(nèi)的事務(wù)在從節(jié)點上就可以并發(fā)執(zhí)行,問題在于如何區(qū)分事務(wù)是否在同一組中的,于是在binlog中出現(xiàn)了兩個新的參數(shù)信息 last_committed 和 sequence_number
Enjoy GreatSQL :)
隨著 MySQL 版本的不斷更新,對 DDL 操作的支持也在不斷的完善和更新:比如從 MySQL 5.6 引入 Online DDL ,在 MySQL 5.7 對 Online DDL 進一步完善,到現(xiàn)在的 8.0 版本,則對 DDL 的實現(xiàn)重新進行了設(shè)計,比如 DDL 操作支持原子特性,在 MySQL 8.0.27 引入并行 DDL 。本篇就來探究一下 MySQL 8.0.27 的并行 DDL 對于 DDL 操作速度的提升。
MySQL 8.0.14 引入了 innodb_parallel_read_threads 變量來控制掃描聚簇索引的并行線程。MySQL 8.0.27 引入了 innodb_ddl_threads 變量來控制用于創(chuàng)建二級索引時的并行線程數(shù)量,此參數(shù)一般和一并引入的 innodb_ddl_buffer_size 一起使用,innodb_ddl_buffer_size 用于指定進行并行 DDL 操作時能夠使用的 buffer 大小,buffer 是在所有的 DDL 并行線程中平均分配的,所以一般如果調(diào)大 innodb_ddl_threads 變量時,也需要調(diào)大 innodb_ddl_buffer_size 的大小。
innodb_ddl_threads 、innodb_ddl_buffer_size 和 innodb_parallel_read_threads 的默認大小分別為:
接下來測試一下調(diào)大 innodb_ddl_threads 、innodb_ddl_buffer_size 和 innodb_parallel_read_threads 參數(shù)值對 DDL 操作的性能提升。
首先創(chuàng)建一張 5000 萬的表:
分別測試不同的線程數(shù)量和緩沖區(qū)大小的 DDL 操作時間,例如:
通過不斷調(diào)整相關(guān)參數(shù)得到以下結(jié)果:
可以看到,隨著并發(fā)線程的增多和 buffer 的增加,DDL 操作所占用的資源也越多,而 DDL 操作所花費的時間則越少。不過通過對比資源的消耗和 DDL 速度的提升比例,最合理的并行線程數(shù)量為4-8個,而 buffer 大小可以根據(jù)情況進行調(diào)整。
參考鏈接: