引言:
最近一直對於並行異步同步的問題存在疑惑,網上只有籠統的解釋,並不能很好的解決疑惑,所以寫了下自己的一些認識,歡迎大家拍磚。
1.關鍵字的解釋:
並行: 一般指並行計算,是說同一時刻有多條指令同時被執行,這些指令可能執行於同一CPU的多核上,或者多個CPU上,或者多個物理主機甚至多個網絡中.
其中並發又有偽並發和真並發,偽並發是指單核處理器的並發,真並發是指多核處理器的並發。
異步:與同步相對應,異步指的是讓CPU暫時擱置當前請求的響應,處理下一個請求,當通過輪詢或其他方式得到回調通知后,開始運行。多線程將異步操作放入另一線程中運行,通過輪詢或回調方法得到完成通知,但是完成端口,由操作系統接管異步操作的調度,通過硬件中斷,在完成時觸發回調方法,此方式不需要占用額外線程。
2.結合代碼的講解:
最好的講解方式莫過於代碼演示,針對並發:
#include <stdio.h> #include <pthread.h> //線程 /***************************************** void *fun2(void *arg){ char s[110]; while(1){ puts("你是handsomecui!"); sleep(2); } } void *fun1(void *arg){ char s[100]; while(1){ scanf("%ss", s); printf("人生自古多無情 : %s\n", s); sleep(3); } } int main(){ pthread_t pid[10]; int i; for(i = 0; i < 10; i++){ if(i & 1) pthread_create(&pid[i], NULL, fun1, NULL); else pthread_create(&pid[i], NULL, fun2, NULL); //pthread_join(pid[i], NULL); } for(i = 0; i < 10; i++){ pthread_join(pid[i], NULL); } return 0; } *************************************************************/ //進程 int main(){ int pid; pid = fork(); if(pid == 0){ while(1){ puts("我是handsomecui!"); sleep(2); } } else{ while(1){ char s[110]; scanf("%s", s); printf("人生自古多無情 : %s\n", s); sleep(3); } } return 0; }
以上通過多進程以及多線程解釋了並發的概念;其實並發就是多線程或者多進程同時執行,注意進行io操作時需要加鎖;
下面詳細講解並行,異步,同步的概念;
代碼:
#include <stdio.h> #include <pthread.h> pthread_mutex_t mutex; void *shaoshui(void *arg){ pthread_mutex_lock(&mutex); sleep(1); puts("prepare for shaoshui!"); pthread_mutex_unlock(&mutex); sleep(8); puts("shaochui finish!"); pthread_mutex_lock(&mutex); sleep(1); puts("shut down water"); pthread_mutex_unlock(&mutex); } void *jugangling(void *arg){ pthread_mutex_lock(&mutex); sleep(10); puts("jugangling finish"); pthread_mutex_unlock(&mutex); } void *xiyifu(void *arg){ pthread_mutex_lock(&mutex); sleep(1); puts("prepare for xiyifu"); pthread_mutex_unlock(&mutex); sleep(5); puts("xiyifu finish"); pthread_mutex_lock(&mutex); sleep(1); puts("shut down xiyiji"); pthread_mutex_unlock(&mutex); } int main(){ pthread_t pth[3]; int begin = time(NULL); pthread_mutex_init(&mutex, NULL); pthread_create(&pth[0], NULL, shaoshui, NULL); pthread_create(&pth[1], NULL, xiyifu, NULL); pthread_create(&pth[2], NULL, jugangling, NULL); int i; for(i = 0; i < 3; i++){ pthread_join(pth[i], NULL); } int end = time(NULL); printf("spend time %d\n", end - begin); return 0; }
舉一個簡單例子, 假設我要做 燒開水,舉杠鈴100下, 洗衣服 3件事情。
燒開水 這件事情, 我要做的事情為, 准備燒開水 1分鍾, 等開水燒開 8 分鍾 , 關掉燒水機 1分鍾
舉杠鈴100下 我要做的事情為, 舉杠鈴100下 10分鍾
洗衣服 我要做的事情為, 准備洗衣服 1分鍾, 等開水燒開 5 分鍾 , 關掉洗衣機 1分鍾
代碼思路:
線程1 准備燒開水 1分鍾, 等開水燒開 8 分鍾 , 關掉燒水機 1分鍾
線程2 舉杠鈴100下 10分鍾
線程3 准備洗衣服 1分鍾, 等開水燒開 5 分鍾 , 關掉洗衣機 1分鍾
單核情況下
同步的完成,我需要做的時間為 1+ 8 +1 + 10 + 1+ 5 +1 = 27 分
如果異步,就是上面的代碼,需要14分鍾,就是在等的時候,我們可以切換去做別的事情
准備燒開水(1) + 准備洗衣服(1) + 舉50下杠鈴 (5)分鍾+ 關洗衣機 1分鍾 + 舉杠鈴20下 (2)分鍾+ 關燒水機 1分鍾 + 舉30下杠鈴(3)分鍾
1+1+5+1+2+1+3 =14 分鍾
那么在多核的情況下,也就是說現在是多個人解決這三個問題,我們就不需要在准備洗衣服等情況下進行加鎖了,你在干這件事情的時候,別的可以交給其他小伙伴:
多核 異步 並行
核1 准備燒開水 1分鍾+ 舉杠鈴50下(5)分鍾+ 等待3分鍾 + 關掉燒水機 1分鍾
核2 准備洗衣服 1分鍾+ 舉杠鈴50下(5)分鍾+ 關掉洗衣機 1分鍾 + 等待3分鍾
其實只花了 1+5+3+1 = 10分鍾
其中還有雙核都等待了3分鍾
那么對於上面的代碼我們完全可以把鎖去掉,相當於多核的情況。
雙核 異步 非並行
核1 舉杠鈴100下(10)分鍾
核2 准備燒開水 1分鍾+ 准備洗衣服 1分鍾+ 等待5 分鍾+ + 關掉燒水機 1分鍾 + 等待 1 分鍾 + 關掉洗衣機 1分鍾
其實只花了 1+5+3+1 = 10分鍾
針對並行與非並行無非就是一件事並行就是可以一起做,非並行則不然。。。
異步和同步的區別, 在io等待的時候,同步不會切走,浪費了時間。
如果都是獨占cpu 的業務, 比如舉杠鈴的業務, 在單核情況下 多線和單線 沒有區別。
多線程的好處,比較容易的實現了 異步切換的思想, 因為異步的程序很難寫的。多線程本身程還是以同步完成,但是應該說
比效率是比不上異步的。 而且多線很容易寫, 相對效率也高。
多核的好處,就是可以同時做事情, 這個和單核完全不一樣的。
實例參考: http://blog.csdn.net/cqkxboy168/article/details/9026205