gpt4 book ai didi

c - C 标准和 C POSIX 中的 IO

转载 作者:太空宇宙 更新时间:2023-11-04 03:43:14 25 4
gpt4 key购买 nike

我在测试 C 标准和 C POSIX 之间的不同 IO 函数时遇到问题。

我编写了两个程序,逐个字符地读取作为参数传递的文件,并在读取后立即显示每个字符。这些程序将由共享相同描述符和相同行为的三个进程组成(每个进程的标识以读取的字符显示)。

第一个程序将使用 POSIX 标准函数(打开、读取)编写

int main(int argc, char **argv){
int fd; /* Descriptor */
char *fic = argv[1]; /* Le nom du fichier */
int end = 0;

/* Sémaphore */
struct sembuf operation;
int sem_id;
sem_id = semget(ftok(fic, 'S'), 1, 0666|IPC_CREAT);
semctl(sem_id, 0, SETVAL, 1);

if((fd = open(fic, O_RDONLY, 0666))==-1){
perror("open file\n");
}

int i = 0;
char c;
for(i=0; i<3; i++){
if(fork()==0){
/* Lire */
while(end==0){
operation.sem_num = 0;
operation.sem_op = -1;
semop(sem_id, &operation, 1);

if(read(fd, &c, sizeof(char))>0){
printf("[Pid=%d]%c\n", getpid(), c);
}
else{
end = 1;
break;
}

operation.sem_num = 0;
operation.sem_op = 1;
semop(sem_id, &operation, 1);
sleep(1);
}
return EXIT_SUCCESS;
}
else continue;
}

for(i=0; i<3; i++){
wait(NULL);
}

close(fd);
semctl(sem_id, 0, IPC_RMID, NULL);
return EXIT_SUCCESS;
}

第二个程序将使用 C 库函数(fopen、fgetc)编写

int main(int argc, char **argv){
FILE *fd; /* Descriptor */
char *fic = argv[1];
int end = 0;

/* Sémaphore */
struct sembuf operation;
int sem_id;
sem_id = semget(ftok(fic, 'S'), 1, 0666|IPC_CREAT);
semctl(sem_id, 0, SETVAL, 1);

if((fd = fopen(fic, "r"))==NULL){
perror("open file\n");
}

int i = 0;
char c;
for(i=0; i<3; i++){
if(fork()==0){
while(end==0){
operation.sem_num = 0;
operation.sem_op = -1;
semop(sem_id, &operation, 1);

if((c = fgetc(fd))!=EOF){
printf("[Pid=%d]%c\n", getpid(), c);
}
else{
end = 1;
break;
}

operation.sem_num = 0;
operation.sem_op = 1;
semop(sem_id, &operation, 1);
sleep(1);
}
return EXIT_SUCCESS;
}
else continue;
}

for(i=0; i<3; i++){
wait(NULL);
}

fclose(fd);
semctl(sem_id, 0, IPC_RMID, NULL);
return EXIT_SUCCESS;
}

在 C POSIX 的情况下,我发现 3 个进程使用信号量的锁定机制并行工作。但在 C 标准的情况下,只有一个进程在屏幕上读取和显示字符。

谁能告诉我造成这种差异的原因?

非常感谢。

最佳答案

如果我没理解错的话,你运行你的程序并看到这样的输出:

$ echo foo > /tmp/input
$ ./synchronized-read /tmp/input # PIDs differ; the readers "share" the input
[Pid=124] f
[Pid=123] o
[Pid=125] o
[Pid=123] # <-- (newline)

$ ./synchronized-fgetc /tmp/input # PIDs are all the same; one reader reads all
[Pid=567] f
[Pid=567] o
[Pid=567] o
[Pid=567] # <-- (newline)

原因是read直接对文件进行操作,而 fgetc在缓冲的标准 IO 流上运行。

因此,在第一个程序中,读取器每次直接从文件中读取一个字节。在第二个程序中,第一个获得信号量的读者读取整个文件——你没有向我们展示样本输入,但这符合你的问题描述——这意味着其他读者立即遇到 EOF 并退出。

如果您将每个中的子逻辑修改为 printf("[Pid=%d]EOF\n", getpid()) 在输入结束时,您会清楚地看到它。

关于c - C 标准和 C POSIX 中的 IO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26827347/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com