2019-2020-1 20175302 20175314 20175316 實驗三 併發程序

2019-2020-1 20175302 201752314 20175316 實驗三 併發程序

實驗三 併發程序-1

實驗內容

學習使用Linux命令wc(1);
基於Linux Socket程序設計實現wc(1)服務器(端口號是你學號的後6位)和客戶端;
客戶端傳一個文本文件給服務器;
服務器返加文本文件中的單詞數。html

設計實現

  • 命令參數
    -c:統計字節數
    -l:統計行數
    -m:統計字符數。這個標誌不能與 -c 標誌一塊兒使用。
    -w:統計字數。一個字被定義爲由空白、跳格或換行字符分隔的字符串
    -L:打印最長行的長度
    -help:顯示幫助信息
    --version:顯示版本信息
    linux

  • 實現僞代碼
    int main() { fd = fopen()//打開文件; fscanf()//對文件的內容以字符串的形式進行讀取 if..count++//設置條件,當知足字符串條件時計數; }
    對於wc -w功能與咱們統計單詞個數類似,而其實現時:由' ','\n','\t','\r'做爲分隔符
    統計單詞個數時,除上述分隔符,還加入了文本文件中常見的符號:'!','"','?','.',',','(',')',':',';','-'做爲分隔符算法

  • 實現wc -w
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFERSIZE 1024

int main()
{
    FILE *fp;
    char ch;
    char filename[100];
    int flag=0,num=0;
        printf("input filename: ");
    scanf("%s",filename);
    if((fp = fopen(filename,"r"))==NULL)
    {
        printf("Failure to open %s\n",filename);
        exit(0);
    }
    while((ch=fgetc(fp))!=EOF)
    {
        if(ch==' ' || ch=='\n' || ch=='\t' || ch=='\r')
        {
            flag=0;
        }
        else
        {
            if(flag==0)
            {
                flag=1;
                num++;
            }

        }

    }
    printf("%c\n",num+48);
    fclose(fp);
    return 0;
}
  • wc txt
    安全

  • 實現單詞個數統計
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFERSIZE 1024
/*int num=0;
void wc(char buffer[],int size)
{
    int i,flag=0;
    for(i=0;i<size;i++)
    {
        if(buffer[i]==' ' || buffer[i]=='\n' || buffer[i]=='\t' || buffer[i]=='\0' || buffer[i]=='!' || buffer[i]=='?' || buffer[i]=='"' || buffer[i]=='.' || buffer[i]== ',' || buffer[i]==':' || buffer[i]=='(' || buffer[i]==')' || buffer[i]==';' || buffer[i]=='■ ' || buffer[i]=='•' )
        {
            flag=0;
        }
        else
        {
            if(flag==0)
            {
                num++;
            }
            flag=1;
        }
    }
    return num;
}*/
int main()
{
    FILE *fp;
    char ch;
    char filename[100];
    int flag=0,num=0;
        printf("input filename: ");
    scanf("%s",filename);
    if((fp = fopen(filename,"r"))==NULL)
    {
        printf("Failure to open %s\n",filename);
        exit(0);
    }
    while((ch=fgetc(fp))!=EOF)
    {
        if(ch==' ' || ch=='\n' || ch=='\t' ||  ch=='\!' || ch=='\?' || ch=='\"' || ch=='\.' || ch== '\,' || ch=='\:' || ch=='\(' || ch=='\)'     || ch=='\;' || ch=='\-')
        {
            flag=0;
        }
        else
        {
            if(flag==0)
            {
                flag=1;
                num++;
            }

        }

    }
    printf("%d\n",num);
    fclose(fp);
    return 0;
}
  • 客戶端和服務器的通訊過程
    服務器

  • 運行結果
    網絡

實驗三 併發程序-2

實驗內容

使用多線程實現wc服務器並使用同步互斥機制保證計數正確;
對比單線程版本的性能,並分析緣由。數據結構

多線程

  • 同步
    直接制約關係
    加入同步機制主要是爲了在多線程程序中,若是須要對某個共享資源C進行同步訪問,若是系統沒有調度到B,A也是沒有可能訪問C的,必須等B調度到以後,A纔可能從新訪問。多線程

  • 互斥鎖
    主要用來保護臨界資源
    臨界資源,就是有可能多個線程都須要訪問的數據地址,也有多是某一段代碼,執行這段代碼有可能會改變多個線程都須要訪問的數據。併發

  • 多線程實現wc服務器時,會出現多個客戶端同時像服務器傳送文件的狀況,須要根據發送的不一樣文件名建立新的接收文件,並要確立好調度順序關係高併發

運行截圖

  • 對比單線程版本的性能,並分析緣由
  • 緣由:全部數據結構的生存期,以及對這些數據結構的access,都用這一根邏輯線程,不須要考慮數據結構的race。把任何耗時的操做都給其餘線程(IO線程、定時器線程,DB線程等)作,作完以後向事件隊列(多線程安全的隊列,其餘線程是生產者,邏輯線程是消費者)丟事件。
  • 多線程邏輯設計的思路:
    全部數據結構的生存期,以及對這些數據結構的access,不必定在一根線程。
    須要考慮數據結構的race。
    網絡事件、定時器事件喚醒工做線程(通常經過iocp或者epoll來喚醒)執行全部工做,通常不須要交換到其餘線程。很顯然,單線程邏輯多了一層事件隊列交換,會增長延遲,以及全部的邏輯都在一根線程上跑,邏輯被阻塞也會帶來延遲。其實吞吐量對於rpc來講,是個宏觀的概念,儘量快地消費網絡消息就會提高吞吐量。
    對於高併發的程序,是沒法忍受單線程邏輯。

實驗三 併發程序-3

實驗內容

  • 交叉編譯多線程版本服務器並部署到實驗箱中;
  • PC機做客戶端測試wc服務器。

    實驗步驟

    1.將實驗箱與電腦相連,參照[實驗一 開發環境的熟悉]的步驟操做,確保目標機(超級終端)和宿主機(虛擬機Ubuntu)能相互ping通(實驗箱IP爲192.168.0.232,Ubantu的IP爲192.168.0.230)。

    2.修改客戶端IP段代碼。
    3.用交叉編譯器arm-none-linux-gnuenbi-gcc編譯server.c

    4.參照[實驗一 開發環境的熟悉],掛載共享目錄,經過NFS把宿主機中的程序運行目錄映射到目標機中。
    5.在超級終端運行服務器armserve,在Ubantu運行客戶端。

實驗中遇到的問題和解決方案

  • 問題一:編譯SM2的C文件時出現找不到庫的問題。
  • 解決方案:輸入兩條命令重裝
sudo apt-get remove openssl libssl-dev
sudo apt-get install openssl libssl-dev -y
  • 問題二:LED與UART代碼編譯不經過
  • 解決方案:將實驗箱接入電源,鏈接實驗箱與電腦,打開Z32下載調試工具軟件資料\Z32下載調試工具\NZDownloadTool.exe,打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,顯示1設備已鏈接後,點擊瀏覽,選擇\實驗 1-LED 閃爍\bin\Z32HUA.bin,點擊下載,綠色進度條加載完成後,程序下載成功

實驗心得與體會

  • 本次實驗利用uVision4破解MDK,經過串口助手實現試驗箱Z32和電腦之間的數據傳輸和通訊,學會了如何下載程序到試驗箱和我國的密算法標準SM1,SM2,SM3,SM4,實驗較爲簡單,但須要調試軟件,須要耐心。

  • SM1:對應密碼學分組密碼算法,普遍應用於電子政務、電子商務及國民經濟的各個應用領域(包括國家政 務通、警務通等重要領域)。

  • SM2:對應密碼學公鑰密碼算法RSA,用於加解密及數字簽名。

  • SM3:對應密碼學摘要算法MD5,適用於商用密碼應用中的數字簽名和驗證。

  • SM4:對應密碼學分組密碼算法DES,用於無限局域網產品使用。

參考資料

相關文章
相關標籤/搜索