2012-03-27 51 views
1

嗨我正在寫一個字符驅動程序讀取和寫入特定的設備。由於我是一個noob,這是一個非常簡單和容易的char驅動器,它只使用最簡單的協議,例如打開,讀取,寫入和釋放。要測試我的驅動程序,我正在使用以下程序... bellow是我的用戶空間程序的源代碼。用戶空間代碼執行的順序是什麼?

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <signal.h> 
#include <poll.h> 

int main(void){ 
int num; 
char *buff; 
FILE *fd = fopen("/dev/hi","a+"); 
num = fprintf(fd,"this is sentence 1 !!"); 
num = fprintf(fd,"this is sentence 2 !!"); 
num = fprintf(fd,"this is sentence 3 !!"); 
num = fprintf(fd,"this is sentence 4 !!"); 
num = fprintf(fd,"this is sentence 5 !!"); 
buff = malloc(sizeof(char) * num+1); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
free(buff); 
close(fd); 
return 0; 
} 

現在它的重要性如何我的驅動程序工作,但是,我以什麼樣的順序,我叫我的讀寫方法。理想情況下,如果驅動程序是按照我編寫代碼的順序寫入的,並按照我編寫代碼的順序讀取的,那將會很好。不過我注意到,如果我寫我的代碼就像...

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <signal.h> 
#include <poll.h> 

int main(void){ 
int num; 
char *buff; 
FILE *fd = fopen("/dev/hi","w"); 
num = fprintf(fd,"this is sentence 1 !!"); 
num = fprintf(fd,"this is sentence 2 !!"); 
num = fprintf(fd,"this is sentence 3 !!"); 
num = fprintf(fd,"this is sentence 4 !!"); 
num = fprintf(fd,"this is sentence 5 !!"); 
    close(fd); 
    fd = fopen("/dev/hi","r"); 
buff = malloc(sizeof(char) * num+1); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
fread(buff,sizeof(char),num+1,fd); 
printf("%s\n",buff); 
free(buff); 
close(fd); 
return 0; 
} 

我發現fprintf中()只有當我關閉文件描述符和最差尚未寫入,執行後,我從我的設備讀取。當然,我想寫我的設備,然後從它讀取,但它不會發生這種情況。這給我的印象是用戶空間中的許多事情同時執行讓我感到困惑。在處理用戶空間時,如何知道我的設備函數被調用的順序。對不起,如果這看起來模糊,我會詳細說明任何鏡像。

感謝您的回覆!

+3

我將使用系統調用'write',而不是標準庫中的'fprintf'或'fputs'。或者至少經常調用fflush。 – 2012-03-27 05:37:27

+0

感謝您的幫助! – 2012-03-27 05:52:28

回答

4

您對'fd'的寫入操作將被緩存,並且只有在關閉後才寫入設備驅動程序。 這是正常的,可以減少系統調用次數。

如果您確實需要將每次寫入發送到設備,請嘗試在每次寫入後向fsync()添加一次調用。 或者,由於它是一個字符驅動程序,它很可能是行緩衝,嘗試在每行的末尾添加'\ n'。

+2

fsync不會這樣做,因爲他使用FILE *(並稱它們爲fds ;-),但fflush應該這樣做。 – flolo 2012-03-27 06:03:21

+0

我認爲添加換行符會阻止緩衝。 – ugoren 2012-03-28 14:01:20

1

調查fflushfsync以清除緩衝輸出,並在讀取之前提交寫入。

+0

請注意,fflush將FILE *作爲參數,而不是文件描述符。他會想要fsync。 – 2012-03-27 05:42:52

+1

@KristofProvost:沒有fflush是對的,混淆來自於原始海報使用FILE *並將其稱爲fd的事實。 – flolo 2012-03-27 06:02:02

+0

哦,你是對的。我真的應該知道比預期一個名爲fd的變量包含文件描述符更好。 – 2012-03-27 06:09:41

2

用戶空間中的代碼按順序執行(除非您使用並行或顯式混合順序的其他概念)。

我懷疑,你解釋爲「mirky」來自fprintf的緩衝。

您可以在每個fprintf後調用fflush(fd)來刷新緩衝區。當您事先致電setbuf(fd, NULL)時,您可以將其禁用。

0

正如其他人所說,這是關於緩衝,而不是一些奇怪的執行順序效應。使用fflush來刷新流並實際寫入數據,或者使用低級別打開,寫入等調用。

但是,我認爲另一件事應該指出的:

你似乎有一些混亂怎麼回事呢流和文件描述符。你打電話給你的FILE *「fd」,然後說它是一個文件描述符。但是FILE *是一個流,而不是文件描述符。文件描述符是一個較低級別的東西,它被stdio庫隱藏。

Linux提供了文件描述符,您可以通過調用開放搞定,然後你可以使用寫入該文件描述符,並與密切關閉它。 stdio庫增加了另一個層次,有自己的電話(FOPENFWRITEfprintf中FCLOSE等),以及它自己的緩衝,對文件描述符的頂部。

另請注意,您應該使用fclose關閉流,而不是關閉