【问题标题】:Problems using the fork function linuxlinux使用fork函数的问题
【发布时间】:2019-12-27 20:05:59
【问题描述】:

我正在尝试实现以下目标:我从输入文本文件中读取 nr 个单词,并且对于每个单词我想启动一个子进程来修改单词并将其返回到输出文本文件中.输出波动,有时我把单词弄乱了(苹果香蕉变成了appbananale),有时输出文件是20kb,它会冻结文本编辑器。

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

    int in, out, i, nr, k, j;
    char buffer[100];

    in = open(argv[1], O_RDONLY);
    if (in == -1){
        perror(NULL);
        return errno;
    }
    out = open(argv[2], O_WRONLY | O_CREAT, 0666);
    if (out == -1){
        perror(NULL);
        return errno;
    }
    if (read(in, buffer, 100) == -1){
        perror(NULL);
        return errno;
    }
    nr = 5;
    k=0;
    srand(time(NULL));
    char v[20];
    int l;
    j=0;
    pid_t pid;
    for (i=1;i<sizeof(buffer);i++){
        if (k == nr) break;

        if (buffer[i]=='\n'){
            k++;
            pid = fork();
            if (pid < 0)
                return errno;
            if (pid == 0){
                //for (l=0;l<j;l++)
                write (out, v, j);
                return 0;
            }
            j=0;
        }
        else{
            j++;
            v[j-1]=buffer[i];   
        }

    }


    return 0;
}


【问题讨论】:

  • “休息无关紧要”。不在 Stackoverflow 上,它不是。请阅读How do I ask a good question?。特别是,要求调试帮助的所有 Stackoverflow 问题都需要发布 minimal verifiable example
  • 在处理访问共享资源的多个进程时,您需要实现同步,以便按照定义的顺序访问共享资源。似乎您没有,因此进程将以交错和随机顺序写入文件。
  • 什么是out?您是否同时从多个进程写入同一个文件描述符?
  • 看起来jj++ 中使用时未初始化,这将导致未定义(不可预测)的行为。是的,完整的代码确认您缺少同步。
  • 关于j,这只是将问题转移到这一行:for (l=0;l&lt;j;l++) 因为j=0 那时尚未执行。而且您不能将buffer[0] 用作这样的数字。您需要使用atoistrtol 将其从ascii 值转换为整数。但是你需要传递一个字符串而不是一个字节。

标签: c linux process fork


【解决方案1】:

您的每个子进程都在写入相同的输出流,并且它们都同时运行,因此它们的输出混合在一起。

不要一次写一个字符,而是写整行。对本地符合 POSIX 的文件系统的 write() 调用是原子的,因此不会在每个进程之间混合数据。

所以换个循环:

for (l=0;l<j;l++)
    write (out, v+l, 1);

write(out, v, j);

请参阅 Atomicity of `write(2)` to a local filesystem 了解有关此问题的各种警告。

【讨论】:

  • 这解决了更大的问题,但现在单词在输出文件中的顺序是随机的。
  • 如果子进程不应该同时运行,那么分叉子进程有什么意义?
  • 您为什么希望它修复它?问题是所有子进程同时运行,因此它们以不可预测的顺序写入。如果您希望所有内容都按顺序编写,为什么还要使用子进程?
  • 如果我仍然想在不同的过程中修改并返回每个单词,我应该怎么做。
  • 您需要在进程之间进行某种形式的同步,以便子 N 在写入之前等待子 N-1。这个比较复杂。
猜你喜欢
  • 1970-01-01
  • 2015-01-22
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 2013-11-24
相关资源
最近更新 更多