В каком порядке выполняется код пользовательского пространства? - PullRequest
1 голос
/ 27 марта 2012

Привет, я пишу драйвер чарта, который читает и пишет на определенное устройство.Так как я новичок, это очень простой и удобный символьный диск, который использует только самые простые протоколы, такие как open, read, write и release.Для проверки моего драйвера я использую следующую программу ... ниже приведен исходный код моей программы пользовательского пространства.

#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 ]

4 голосов
/ 27 марта 2012

Ваши записи в 'fd' кэшируются и записываются в драйвер устройства только после его закрытия.Это нормально и делается для уменьшения количества системных вызовов.

Если вам действительно нужно отправлять каждую запись на устройство, попробуйте добавить вызов к fsync () после каждой записи.В качестве альтернативы, поскольку это драйвер char, скорее всего, он буферизуется строкой, попробуйте добавить '\ n' в конце каждой строки.

2 голосов
/ 27 марта 2012

Код в пространстве пользователя выполняется по порядку (за исключением случаев, когда вы работаете явно с параллелизмом или какой-то другой концепцией, которая смешивает порядок).

Я подозреваю, что то, что вы интерпретируете как "mirky", происходит из буферизации fprintf.

Вы можете очистить буферы, вызывая fflush(fd) после каждого fprintf.И вы можете отключить его, когда будете звонить заранее setbuf(fd, NULL).

1 голос
/ 27 марта 2012

Просмотрите fflush или fsync , чтобы очистить буферизованный вывод и зафиксировать запись перед выполнением чтения.

0 голосов
/ 27 марта 2012

Как уже говорили другие, речь идет о буферизации, а не о каких-то странных эффектах порядка выполнения. Используйте fflush , чтобы очистить поток и фактически записать данные, или используйте низкоуровневые open , write и т. Д.

Но, на мой взгляд, следует отметить еще одну вещь:

Похоже, у вас возникает путаница в отношении потоков и файловых дескрипторов. Вы называете свой FILE * "fd", а затем говорите, что это дескриптор файла. Но FILE * - это поток, а не дескриптор файла. Файловый дескриптор - вещь более низкого уровня, которая скрыта библиотекой stdio.

Linux предоставляет файловые дескрипторы, которые вы получаете, вызывая open , и затем вы можете использовать write для записи в этот файловый дескриптор и закрытия его с помощью close . Библиотека stdio добавляет еще один уровень со своими собственными вызовами ( fopen , fwrite , fprintf , fclose и т. Д.) И собственной буферизацией , поверх файловых дескрипторов.

Также обратите внимание, что вы должны использовать fclose , чтобы закрыть поток, а не close .

...