gpt4 book ai didi

c - 使用 dup2() 写入文件后如何清理文件描述符?

转载 作者:行者123 更新时间:2023-11-30 16:07:43 25 4
gpt4 key购买 nike

我想编写一个程序,将终端传递的参数写入两个名为(fichier,copie)的文件。

首先,两个文件中的参数顺序相同,以及终端中为每个参数使用子进程提供的顺序。

其次,两个文件中的参数顺序相同,尽管它与终端中提供的参数顺序不同。

我已经使用“锁定”编写了下面的代码,以便将每个参数写入两个文件(fichier,copie)中,但似乎我无法将参数写入两个文件中。由于 dup2() 函数,我得到了第二个文件(副本)中写入的所有参数(我认为我的文件描述符有问题)。

如果有人可以向我解释如何清除文件描述符并获取写入两个文件中的参数,我将非常高兴。

命令: ./try hello haha​​ hene

输出:在“copie”文件中,但“fichier”文件为空

  1. 88961 ecrit 哈哈
  2. 88961 ecrit 哈哈
  3. 88962 ecrit hene
  4. 88962 ecrit hene
  5. 88960 ecrit 你好
  6. 88960 一封简短的问候
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void fils(char *chaine){
int fic1 = open("fichier", O_CREAT|O_APPEND|O_WRONLY,S_IRUSR|S_IWUSR);
lseek(fic1 ,0 ,SEEK_SET);
lockf(fic1 ,F_LOCK,0);
dup2(fic1, 1);

printf("%d a ecrit %s\n",getpid(),chaine);
lseek(fic1 ,0 ,SEEK_SET);
lockf(fic1 ,F_ULOCK,0);

int fic2 = open("copie", O_CREAT|O_APPEND|O_WRONLY,S_IRUSR|S_IWUSR);
lseek(fic2 ,0 ,SEEK_SET);
lockf(fic2 ,F_LOCK,0);
dup2(fic2, 1);
printf("%d a ecrit %s\n",getpid(),chaine);

int attente=rand()%2;
fprintf(stderr,"%d attente de %d dans fichier et copie\n",getpid(),attente);
sleep(attente);

lseek(fic2 ,0 ,SEEK_SET);
lockf(fic2 ,F_ULOCK,0);
close(fic1);
close(fic2);

exit(EXIT_SUCCESS);
}

int main(int argc,char **argv){

int i;
pid_t pid;
system("rm -f fichier copie");

for(i=1;i<argc;i++){
if((pid=fork())<0){
printf("Erreur fork\n");
exit(EXIT_FAILURE);
}else if(pid==0){
fils(argv[i]);
}
}
exit(EXIT_SUCCESS);
}

最佳答案

没有向 fichier 写入任何内容,因为您不使用 fflush(stdout) 并且在切换标准输出以写入 copie 之前缓冲区未满.

lseek() 调用大多毫无意义;由于O_APPEND,写入将发生在文件末尾。它们背后的逻辑是确保整个文件被锁定,但是......

lockf() 调用毫无意义; O_APPEND 标志确保写入发生在文件末尾,并且单独进程中单独并发写入调用的内容不会交错存储在磁盘文件中。

将其放在一起,再加上等待子进程终止的循环,会导致:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

static void fils(char *chaine)
{
int fic1 = open("fichier", O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
dup2(fic1, 1);
close(fic1);

printf("%d a ecrit %s\n", (int)getpid(), chaine);
fflush(stdout);

int fic2 = open("copie", O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
dup2(fic2, 1);
close(fic2);
printf("%d a ecrit %s\n", (int)getpid(), chaine);
fflush(stdout);

int attente = rand() % 2;
fprintf(stderr, "%d attente de %d dans fichier et copie\n", (int)getpid(), attente);
sleep(attente);

exit(EXIT_SUCCESS);
}

int main(int argc, char **argv)
{
int i;
pid_t pid;

remove("fichier");
remove("copie");

for (i = 1; i < argc; i++)
{
if ((pid = fork()) < 0)
{
fprintf(stderr, "Erreur fork\n");
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
fils(argv[i]);
}
}

int corpse;
int status;
while ((corpse = wait(&status)) > 0)
{
printf("%d: child %d exited with status 0x%.4X\n",
(int)getpid(), corpse, status);
}
return(EXIT_SUCCESS);
}

当我运行它时,我得到了输出:

$ open29 hello haha hene
95396 attente de 1 dans fichier et copie
95395 attente de 1 dans fichier et copie
95397 attente de 1 dans fichier et copie
95394: child 95397 exited with status 0x0000
95394: child 95396 exited with status 0x0000
95394: child 95395 exited with status 0x0000
$ cat fichier
95395 a ecrit hello
95396 a ecrit haha
95397 a ecrit hene
$ cat copie
95396 a ecrit haha
95395 a ecrit hello
95397 a ecrit hene
$

请注意, children 的 sleep 时间都相同。它在使用 srand() 进行播种时会小心谨慎,以便在不同的子项中具有不同的序列(例如,在每个子项中调用 srand(getpid()),在fils())。

我还运行了保留锁定方案的代码版本,但在调用printf()之后使用fflush(stdout)。输出没有本质上的不同。文件 fichier 包含以下行:hellohenehaha;文件 copie 包含包含 hellohahahene 的行。关键的变化是使用 fflush(stdout); 将数据写入 fichier 以及 copie

关于c - 使用 dup2() 写入文件后如何清理文件描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59545961/

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