久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久


實驗:linux文件讀/寫及上鎖

分享到:
           

    1.實驗目的

    通(tong)過編(bian)寫文(wen)件讀寫及上(shang)鎖(suo)的程序,進一步(bu)熟(shu)悉Linux中文(wen)件I/O相關的應用開發,并且熟(shu)練掌握open()、read()、write()、fcntl()等函數(shu)的使用。

    2.實驗(yan)內容

    在Linux中FIFO是一(yi)種進程間的(de)管道通(tong)信機制(zhi),Linux支持完(wan)整的(de)FIFO通(tong)信機制(zhi)。

    本(ben)實驗內容比(bi)較(jiao)有趣,我們通(tong)過使用文件操作,仿真FIFO(先(xian)進先(xian)出)結(jie)構及生產者—消費(fei)者運行模型(xing)。

    本實驗中需要打開(kai)兩個(ge)虛(xu)擬終端,分別運行生產(chan)者(zhe)程(cheng)序(xu)(producer)和消(xiao)費者(zhe)程(cheng)序(xu)(customer),此(ci)時兩個(ge)進程(cheng)同(tong)時對同(tong)一個(ge)文件(jian)(jian)進行讀寫操作。因為這(zhe)個(ge)文件(jian)(jian)是(shi)臨界資(zi)源(yuan),所(suo)以可以使用文件(jian)(jian)鎖機制(zhi)來保(bao)證(zheng)兩個(ge)進程(cheng)對文件(jian)(jian)的訪問(wen)都(dou)是(shi)原子操作。

    先(xian)啟動生(sheng)(sheng)產(chan)者(zhe)進程(cheng),它負責創建(jian)仿真FIFO結構的文(wen)件(jian)(其實是(shi)一個普通文(wen)件(jian))并投入生(sheng)(sheng)產(chan),就是(shi)按(an)照(zhao)給定(ding)的時(shi)間間隔,向FIFO文(wen)件(jian)寫入自動生(sheng)(sheng)成的字(zi)(zi)符(在(zai)程(cheng)序(xu)中用(yong)宏定(ding)義選擇使用(yong)數字(zi)(zi)還是(shi)使用(yong)英文(wen)字(zi)(zi)符),生(sheng)(sheng)產(chan)周期(qi)及要(yao)生(sheng)(sheng)產(chan)的資(zi)源(yuan)數通過參數傳遞(di)給進程(cheng)(默認(ren)生(sheng)(sheng)產(chan)周期(qi)為(wei)1s,要(yao)生(sheng)(sheng)產(chan)的資(zi)源(yuan)總數為(wei)10個字(zi)(zi)符,顯然默認(ren)生(sheng)(sheng)產(chan)總時(shi)間為(wei)10s)。

    后啟動的(de)消(xiao)費(fei)者進(jin)程按照給定的(de)數(shu)目進(jin)行消(xiao)費(fei),首先從(cong)(cong)文(wen)件(jian)中讀(du)取相應(ying)數(shu)目的(de)字(zi)符并(bing)在屏(ping)幕上顯示,然后從(cong)(cong)文(wen)件(jian)中刪(shan)除剛才消(xiao)費(fei)過(guo)的(de)數(shu)據。為(wei)了仿真FIFO結構(gou),此時需要使用兩次(ci)(ci)復制(zhi)來實現文(wen)件(jian)內容(rong)的(de)偏移(yi)。每次(ci)(ci)消(xiao)費(fei)的(de)資源(yuan)數(shu)通過(guo)參數(shu)傳遞給進(jin)程,默認值為(wei)10個(ge)字(zi)符。

    3.實驗步驟

    (1)畫出實驗流(liu)程圖(tu)。

    本實驗的兩個程(cheng)序的流(liu)程(cheng)圖如圖2.5所示(shi)。


圖(tu)2.5 文件讀寫及上鎖實驗流程圖(tu)

    (2)編(bian)寫代碼(ma)。

    本實驗(yan)中的(de)生產者(zhe)程序(xu)的(de)源代碼如下所示(shi),其中用(yong)到(dao)的(de)lock_set()函數可參見后(hou)面章節。

    /* producer.c */
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>
    #include "mylock.h"

    #define MAXLEN 10 /* 緩沖區大小大值 */
    #define ALPHABET 1 /* 表示使用英文字符 */
    #define ALPHABET_START 'a' /* 頭一個字符,可以用 'A' */
    #define COUNT_OF_ALPHABET 26 /* 字母字符的個數 */

    #define DIGIT 2 /* 表示使用數字字符 */
    #define DIGIT_START '0' /* 頭一個字符 */
    #define COUNT_OF_DIGIT 10 /* 數字字符的個數 */

    #define SIGN_TYPE ALPHABET /* 本實例選用英文字符 */
    const char *fifo_file = "./myfifo";/* 仿真FIFO文件名 */
    char buff[MAXLEN]; /* 緩沖區 */

    /* 功能:生產一個字符并寫入到仿真FIFO文件中 */
    int product(void)
    {
        int fd;
        unsigned int sign_type, sign_start, sign_count, size;
        static unsigned int counter = 0;

        /* 打開仿真FIFO文件 */
        if ((fd = open(fifo_file, O_CREAT|O_RDWR|O_APPEND, 0644)) < 0)
        {
            printf("Open fifo file error\n");
            exit(1);
        }

        sign_type = SIGN_TYPE;
        switch(sign_type)
        {
            case ALPHABET:/* 英文字符 */
            {
                sign_start = ALPHABET_START;
                sign_count = COUNT_OF_ALPHABET;
            }
            break;

            case DIGIT:/* 數字字符 */
            {
                sign_start = DIGIT_START;
                sign_count = COUNT_OF_DIGIT;
            }
            break;

            default:
            {
                return -1;
            }
        }/*end of switch*/

        sprintf(buff, "%c", (sign_start + counter));
        counter = (counter + 1) % sign_count;

        lock_set(fd, F_WRLCK); /* 上寫鎖 */
        if ((size = write(fd, buff, strlen(buff))) < 0)
        {
            printf("Producer: write error\n");
            return -1;
        }
        lock_set(fd, F_UNLCK); /* 解鎖 */

        close(fd);
        return 0;
    }

    int main(int argc ,char *argv[])
    {
        int time_step = 1; /* 生產周期 */
        int time_life = 10; /* 需要生產的資源總數 */

        if (argc > 1)
        {/* 第一個參數表示生產周期 */
            sscanf(argv[1], "%d", &time_step);
        }
        if (argc > 2)
        {/* 第二個參數表示需要生產的資源數 */
            sscanf(argv[2], "%d", &time_life);
        }
        while (time_life--)
        {
            if (product() < 0)
            {
                break;
            }
            sleep(time_step);
        }

        exit(EXIT_SUCCESS);
    }

 &nbsp;  本(ben)實驗中的消費者程序(xu)的源代碼如下所示:

    /* customer.c */
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <fcntl.h>

    #define MAX_FILE_SIZE 100 * 1024 * 1024 /* 100M */

    const char *fifo_file = "./myfifo"; /* 仿真FIFO文件名 */
    const char *tmp_file = "./tmp"; /* 臨時文件名 */

    /* 資源消費函數 */
    int customing(const char *myfifo, int need)
    {
        int fd;
        char buff;
    int counter = 0;

        if ((fd = open(myfifo, O_RDONLY)) < 0)
        {
            printf("Function customing error\n");
            return -1;
        }

        printf("Enjoy:");
        lseek(fd, SEEK_SET, 0);
        while (counter < need)
        {
            while ((read(fd, &buff, 1) == 1) && (counter < need))
            {
                fputc(buff, stdout); /* 消費就是在屏幕上簡單的顯示 */
                counter++;
            }
        }
        fputs("\n", stdout);
        close(fd);
        return 0;
    }

    /* 功能:從sour_file文件的offset偏移處開始,
    將count字節數據復制到dest_file文件 */
    int myfilecopy(const char *sour_file,
    const char *dest_file, int offset, int count, int copy_mode)
    {
        int in_file, out_file;
        int counter = 0;
        char buff_unit;

        if ((in_file = open(sour_file, O_RDONLY|O_NONBLOCK)) < 0)
        {
            printf("Function myfilecopy error in source file\n");
            return -1;
        }

        if ((out_file = open(dest_file, O_CREAT|O_RDWR|O_TRUNC|O_NONBLOCK, 0644)) < 0)
        {
            printf("Function myfilecopy error in destination file:");
            return -1;
        }

        lseek(in_file, offset, SEEK_SET);
        while ((read(in_file, &buff_unit, 1) == 1) && (counter < count))
        {
            write(out_file, &buff_unit, 1);
            counter++;
        }

        close(in_file);
        close(out_file);
        return 0;
    }

    /* 功能:實現FIFO消費者 */
    int custom(int need)
    {
        int fd;

        /* 對資源進行消費,need表示該消費的資源數目 */
        customing(fifo_file, need);

        if ((fd = open(fifo_file, O_RDWR)) < 0)
        {
            printf("Function myfilecopy error in source_file:");
            return -1;
        }

        /* 為了模擬FIFO結構,對整個文件內容進行平行移動 */
        lock_set(fd, F_WRLCK);
        myfilecopy(fifo_file, tmp_file, need, MAX_FILE_SIZE, 0);
        myfilecopy(tmp_file, fifo_file, 0, MAX_FILE_SIZE, 0);
        lock_set(fd, F_UNLCK);
        unlink(tmp_file);
        close(fd);
        return 0;
    }

    int main(int argc ,char *argv[])
    {
        int customer_capacity = 10;

        if (argc > 1) /* 第一個參數指定需要消費的資源數目,默認值為10 */
        {
            sscanf(argv[1], "%d", &customer_capacity);
        }
        if (customer_capacity > 0)
        {
            custom(customer_capacity);
        }
        exit(EXIT_SUCCESS);
    }

    (3)先在宿(su)主機上(shang)編譯該程序,如下所示:

    $ make clean; make

    (4)在確保沒有編譯錯誤后,交叉編譯該程序,此時需(xu)要修改Makefile中的變量。

    CC = arm-linux-gcc /* 修改Makefile中的編譯器 */
    $ make clean; make

&nbsp;   (5)將生成的(de)可執行(xing)程序下載到目標板(ban)上運(yun)行(xing)。

    4.實(shi)驗結(jie)果

    此實驗(yan)在目標板上的運行(xing)結(jie)果如下所(suo)示(shi)。實驗(yan)結(jie)果會和這(zhe)兩個(ge)進程(cheng)(cheng)運行(xing)的具(ju)體過程(cheng)(cheng)相關,希望讀者能具(ju)體分析每種(zhong)情(qing)況(kuang),下面列出其中(zhong)一種(zhong)情(qing)況(kuang)。

    終端一:

    $ ./producer 1 20 /* 生產周期為1s,需要生產的資源總數為20個 */
    Write lock set by 21867
    Release lock by 21867
    Write lock set by 21867
    Release lock by 21867
    …

    終(zhong)端二(er):

    $ ./customer 5 /* 需要消費的資源數為5個 */
    Enjoy:abcde /* 對資源進行消費,即打印到屏幕上 */
    Write lock set by 21872 /* 為了仿真FIFO結構,進行兩次復制 */
&nbsp;&nbsp;  Release lock by 21872

 &nbsp;  在(zai)兩個(ge)進(jin)程結束后,仿(fang)真FIFO文件的(de)內容如下:

    $ cat myfifo
    fghijklmnopqr /* a到(dao)e的5個字符(fu)已經被消費,就剩下后面15個字符(fu) */

    本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》

   熱點(dian)鏈(lian)接(jie):

   1、linux 文件鎖的實現及其應用
   2、嵌入式Linux串口應用編程之串口讀寫
   3、Linux文件系統之虛擬文件系統
   4、標準I/O操作函數詳解
   5、標準I/O操作的緩沖存儲類型

更多新聞>>