日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

嵌入式Linux基础学习笔记-文件IO编程-文件锁(2)

發布時間:2024/4/18 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 嵌入式Linux基础学习笔记-文件IO编程-文件锁(2) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文件操作仿真FIFO,實現生產者-消費者運行模型

  • 編程實現生產者程序producer.c,創建仿真FIFO結構文件(普通文件),按照給定的時間間隔向FIFO文件寫入自動生成的字符(自定義),生產周期及生產的資源數通過參數傳遞給進程。
  • 編程實現消費者程序customer.c,從文件中讀取相應數目的字符并在屏幕上顯示,然后從文件中刪除剛才消費過的數據,可通過兩次幅值來實現文件內容的偏移,每次消費的資源通過參數傳遞給進程。
  • 在兩個終端上分別運行生產者程序producer和消費者程序customer
  • 生產者消費者問題(英語:Producer-consumer problem),也稱有限緩沖問題(英語:Bounded-buffer problem),是一個多線程同步問題的經典案例。
    該問題描述了共享固定大小緩沖區的兩個線程——即所謂的“生產者”和“消費者”——在實際運行時會發生的問題。生產者的主要作用是生成一定量的數據放到緩沖區中,然后重復此過程。與此同時,消費者也在緩沖區消耗這些數據。該問題的關鍵就是要保證生產者不會在緩沖區滿時加入數據,消費者也不會在緩沖區中空時消耗數據。
    .
    要解決該問題,就必須讓生產者在緩沖區滿時休眠(要么干脆就放棄數據),等到下次消費者消耗緩沖區中的數據的時候,生產者才能被喚醒,開始往緩沖區添加數據。同樣,也可以讓消費者在緩沖區空時進入休眠,等到生產者往緩沖區添加數據之后,再喚醒消費者。通常采用進程間通信的方法解決該問題。如果解決方法不夠完善,則容易出現死鎖的情況。出現死鎖時,兩個線程都會陷入休眠,等待對方喚醒自己。該問題也能被推廣到多個生產者和消費者的情形。

  • 建立lock_set.c文件
  • /* lock_set.c */ int lock_set(int fd, int type) {struct flock old_lock, lock;lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0;lock.l_type = type;lock.l_pid = -1;/* 判斷文件是否可以上鎖 */fcntl(fd, F_GETLK, &lock);if (lock.l_type != F_UNLCK){/* 判斷文件不能上鎖的原因 */if (lock.l_type == F_RDLCK) /* 該文件已有讀取鎖 */{printf("Read lock already set by %d\n", lock.l_pid);}else if (lock.l_type == F_WRLCK) /* 該文件已有寫入鎖 */{printf("Write lock already set by %d\n", lock.l_pid);} }/* l_type 可能已被F_GETLK修改過 */lock.l_type = type;/* 根據不同的type值進行阻塞式上鎖或解鎖 */if ((fcntl(fd, F_SETLKW, &lock)) < 0){printf("Lock failed:type = %d\n", lock.l_type);return 1;} switch(lock.l_type){case F_RDLCK:{printf("Read lock set by %d\n", getpid());}break;case F_WRLCK:{printf("Write lock set by %d\n", getpid());}break;case F_UNLCK:{printf("Release lock by %d\n", getpid());return 1;}break;default:break;}/* end of switch */ return 0; }
  • 編寫生產者程序:
  • #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include "lock_set.c"#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); }
  • 編寫消費者程序:
  • /* 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 errorindestination 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); }
  • 測試-生產者程序
  • 測試-消費者程序
  • 總結

    以上是生活随笔為你收集整理的嵌入式Linux基础学习笔记-文件IO编程-文件锁(2)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。