生活随笔
收集整理的這篇文章主要介紹了
嵌入式Linux基础学习笔记-文件IO编程-文件锁(2)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文件操作仿真FIFO,實現生產者-消費者運行模型
編程實現生產者程序producer.c,創建仿真FIFO結構文件(普通文件),按照給定的時間間隔向FIFO文件寫入自動生成的字符(自定義),生產周期及生產的資源數通過參數傳遞給進程。編程實現消費者程序customer.c,從文件中讀取相應數目的字符并在屏幕上顯示,然后從文件中刪除剛才消費過的數據,可通過兩次幅值來實現文件內容的偏移,每次消費的資源通過參數傳遞給進程。在兩個終端上分別運行生產者程序producer和消費者程序customer
生產者消費者問題(英語:Producer-consumer problem),也稱有限緩沖問題(英語:Bounded-buffer problem),是一個多線程同步問題的經典案例。
該問題描述了共享固定大小緩沖區的兩個線程——即所謂的“生產者”和“消費者”——在實際運行時會發生的問題。生產者的主要作用是生成一定量的數據放到緩沖區中,然后重復此過程。與此同時,消費者也在緩沖區消耗這些數據。該問題的關鍵就是要保證生產者不會在緩沖區滿時加入數據,消費者也不會在緩沖區中空時消耗數據。
.
要解決該問題,就必須讓生產者在緩沖區滿時休眠(要么干脆就放棄數據),等到下次消費者消耗緩沖區中的數據的時候,生產者才能被喚醒,開始往緩沖區添加數據。同樣,也可以讓消費者在緩沖區空時進入休眠,等到生產者往緩沖區添加數據之后,再喚醒消費者。通常采用進程間通信的方法解決該問題。如果解決方法不夠完善,則容易出現死鎖的情況。出現死鎖時,兩個線程都會陷入休眠,等待對方喚醒自己。該問題也能被推廣到多個生產者和消費者的情形。
建立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
);} }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;
}
編寫生產者程序:
#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'
#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 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;}
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
);
}
測試-生產者程序
測試-消費者程序
總結
以上是生活随笔為你收集整理的嵌入式Linux基础学习笔记-文件IO编程-文件锁(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。