天天看點

【Linux基礎】綜合實驗:檔案讀寫及上鎖

1. 實驗目的 通過編寫檔案讀寫及上鎖的程式,進一步熟悉Linux中檔案I/O相關的應用開發,并且熟練掌握open()、read()、write()、fcntl()等函數的使用。 2. 實驗内容 在Linux中FIFO(先進先出)是一種程序間的管道通信機制。本實驗通過使用檔案操作,仿真FIFO結構以及生産者-消費者運作模型。 3. 實驗步驟 (1)流程圖 該實驗流程圖如圖所示

【Linux基礎】綜合實驗:檔案讀寫及上鎖

01.jpg (31.97 KB, 下載下傳次數: 0)

下載下傳附件 儲存到相冊 設為封面

7 天前 上傳

(2)程式說明 本實驗需要打開兩個虛拟終端,分别運作生産者程式(producer)和消費者程式(customer)。此時兩個程序同時對同一個檔案進行讀寫操作。因為這個檔案是臨界資源,是以可以使用檔案鎖機制保證兩個程序對檔案的通路都是原子操作。 先啟動生産者程序,它負責建立仿真FIFO結構檔案(實際是一個普通檔案)并投入生産,就是按照給定的時間間隔,向FIFO檔案寫入自動生成的字元(在程式中用宏定義選擇使用數字還是使用英文字元),生産周期以及要生産的資源數通過參數傳遞給程序(預設生産周期1S,要生産的資源數為10個字元)。 後啟動的消費者程序按照給定的數目進行消費,首先從檔案中讀取相應數目的字元并在螢幕顯示,然後從檔案中删除剛才消費過的資料。為了仿真FIFO結構,此時需要使用兩次複制來實作檔案内容的偏移。每次消費的資源數通過參數傳遞給程序,預設值為10個字元。 (3)代碼 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); } } lock.l_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; } return 0; } 本實驗中的生産者程式的源代碼如下所示,其中用到的lock_set()函數。 #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' #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"; char buff[MAXLEN]; int product(void) { int fd; unsigned int sign_type, sign_start, sign_count, size; static unsigned int counter = 0; 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; } } 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); } 本實驗中的消費者程式的源代碼如下所示。 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #define MAX_FILE_SIZE 100 * 1024 * 1024 const char *fifo_file = "./myfifo"; 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; } 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 errorin 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; } int custom(int need) { int fd; customing(fifo_file, need); if ((fd = open(fifo_file, O_RDWR)) < 0) { printf("Function myfilecopy error in source_file:"); return -1; } 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) { sscanf(argv[1], "%d", &customer_capacity); } if (customer_capacity > 0) { custom(customer_capacity); } exit(EXIT_SUCCESS); } 4、實驗結果 此實驗的運作結果如下所示。實驗結果會和這兩個程序運作的具體過程相關。 終端一: # ./producer 1 15 Write lock set by 11867 Release lock by 11867 …… 終端二: # ./customer 5 Enjoy:abcde Write lock set by 11879 Release lock by 11879   本文轉載于唯C教育,【Linux基礎】綜合實驗:檔案讀寫及上鎖

http://www.weicedu.com/forum.php?mod=viewthread&tid=104&fromuid=4

(出處: http://www.weicedu.com/)

繼續閱讀