用户空间代码以什么顺序执行?

时间:2012-03-27 05:34:32

标签: c linux-kernel kernel driver smp

您好我正在写一个读取和写入特定设备的char驱动程序。由于我是菜鸟,这是一个非常简单易用的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()仅在我关闭文件描述符时写入,而最差的是在我从设备读取后执行。当然,我想写入我的设备,然后从中读取,但它不会发生。这给我的印象是,用户空间中的许多东西同时执行,令我感到困惑。在处理用户空间时,如何知道设备函数的调用顺序。对不起,如果这看起来很模糊,我会详细说明任何有关它的事情。

感谢您的回复!!

4 个答案:

答案 0 :(得分:4)

你对'fd&#39;的写正在缓存,只有在关闭它后才会写入设备驱动程序。 这是正常的,可以减少系统调用次数。

如果您确实需要将每个写入发送到设备,请尝试在每次写入后添加对fsync()的调用。 或者,因为它是一个char驱动程序,它很可能是行缓冲,尝试添加&#39; \ n&#39;在每一行的末尾。

答案 1 :(得分:2)

用户空间中的代码按顺序执行(除非您使用并行性或其他混合顺序的概念进行显式处理)。

我怀疑,你解释为“mirky”的东西来自于fprintf的缓冲。

您可以在每个fprintf之后调用fflush(fd)来刷新缓冲区。您可以在事先致电setbuf(fd, NULL)时将其停用。

答案 2 :(得分:1)

查看fflushfsync以清除缓冲输出,并在读取之前提交写入。

答案 3 :(得分:0)

正如其他人所说,它是关于缓冲,而不是一些奇怪的执行顺序效果。使用 fflush 刷新流并实际写入数据,或使用较低级别的打开写入等来电。

但我认为应该指出另一件事:

你似乎对流和文件描述符有些困惑。你调用 FILE * “fd”,然后说它是文件描述符。但 FILE * 是一个流,而不是文件描述符。文件描述符是一个较低级别的东西,它被stdio库隐藏。

Linux提供文件描述符,您可以通过调用打开获得,然后您可以使用写入写入该文件描述符,并使用关闭它来关闭它即可。 stdio库增加了另一个级别,有自己的调用( fopen fwrite fprintf fclose 等),和它自己的缓冲,在文件描述符之上。

另请注意,您应使用 fclose 关闭流,而不是关闭