淺談並發並行異步同步


引言:

最近一直對於並行異步同步的問題存在疑惑,網上只有籠統的解釋,並不能很好的解決疑惑,所以寫了下自己的一些認識,歡迎大家拍磚。

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

轉載請注明地址:http://www.cnblogs.com/handsomecui/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM