c - C进程在fork()之后打印两次,即使它在父进程内部并且我刷新了stdout

标签 c linux printf buffer shared-memory

我正在为一个学校的C项目工作,该项目涉及使用共享内存,但是我似乎无法弄清楚为什么父进程在派生后两次打印结果。我在打印后刷新标准输出,但它仍然打印两次。
这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <fcntl.h>

/* Defining system macros to avoid magic numbers */
#define TRUE 1
#define FALSE 0
#define MEM_SIZE sizeof(collatz_data)
#define NAME "OS"
#define SEQ_SIZE 50

/* A data struct that will be put into the shared memory to store our values */
typedef struct {
    int starting_number;
    int sequence[SEQ_SIZE];
    int seq_count;
    int is_finished;
} collatz_data;

/* Function for calculating the collatz formula */
int calculate_collatz(int n) {
    return (n % 2 == 0) ?  (n / 2) : (3 * n + 1);
}

/* Shared memory passing project main run loop */
int main(int argc, char *argv[]) {
    
    int shm_fd;
    pid_t pid;
    collatz_data *shared_memory;
    
    /* Requirement 1: Check to see if the number passed on the command line is positive */
    if (argv[1] <= 0) {
        printf("The number you entered was not positive.\n Exiting program...\n");
        exit(1);
    }
    
    /* Getting the number from the command line using atoi function to turn character into int */
    int number = atoi(argv[1]);
    
    printf("\n");
    
    /* Create the shared memeory segment & configure it's size*/
    shm_fd = shm_open(NAME, O_CREAT | O_RDWR, 0666);
    ftruncate(shm_fd, MEM_SIZE);
    
    /* Map the shaerd memory segment to this address space */
    shared_memory = mmap(0, MEM_SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
    
    /* Check to see that our shared memory segment was mapped correctly */
    if (shared_memory == MAP_FAILED) {
        printf("Map Failed\n");
        return -1;
    }
    
    
    /* Fork the current process and create a child */
    fflush(stdout);
    pid = fork();

      /* Check if the fork failed */
      if ((pid=fork()) == -1) {
          perror("Fork Failed");
          
          /* Kill the program */
          exit(1);
      }

     // Child
     else if (pid == 0) {

         int i = 0;
         int n = shared_memory->starting_number;
         
         /* Make the first number in the sequence the number from the command line */
         shared_memory->sequence[i++] = n;
         
         /* Calculate the collatz sequence by storing the numbers in our shared memory sequence */
         while (n != 1 && i < SEQ_SIZE) {
             n = calculate_collatz(n);
             shared_memory->sequence[i++] = n; // Store the next number
         }
         
         /* Store the size of our sequence so the parent can loop over this number later to print it out*/
         shared_memory->seq_count = i;

         // Kill the child process
         exit(0);
     }
      
      // Parent
         else if (pid > 0) {
             
             /* Requirement 2: Pass the input from the command line to the child process */
             shared_memory->starting_number = number;
             
             /* Requirement 4: Inoviking wait will the child calculates the sequence */
             wait(NULL);
             
             printf("Collatz Sequence for number (%d): \n", number);

             /* Requirement 5: Print out collatz results generated by the child */
             for (int i = 0; i < shared_memory->seq_count; i++) {
                 printf("%d ", shared_memory->sequence[i]);
             }
             printf("\n");
             fflush(stdout);
             
             exit(0);
         }
    
     /* Remove the shared memory object */
     shm_unlink(NAME);

    return 0;
}
输出应为:
Collat​​z数字的序列(99):
99298149448224112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

但是由于某种原因,整个东西被打印两次。关于我在做什么错的任何想法?
谢谢。

最佳答案

想通了这一点。
改变了这个:

if ((pid=fork()) == -1) {
      perror("Fork Failed");
      
      /* Kill the program */
      exit(1);
  }
为此:
if (pid == -1) {
      perror("Fork Failed");
      
      /* Kill the program */
      exit(1);
 }
原来,我有一个完整的其他进程正在运行完全相同的代码。删除后,问题解决了。

关于c - C进程在fork()之后打印两次,即使它在父进程内部并且我刷新了stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64294397/

相关文章:

linux - 了解嵌入式板上经过验证的 Uboot

c - 玩转指针,被 char * 字符串弄得晕头转向

c - C 中字符串的开头和结尾对齐

c++ - 为什么不在 C++ 中使用 printf()

c - STM8微 Controller STVD IDE中的汇编指令

可以使用 MPI_Send 和 MPI_Recv 发送数组内的数组吗?

c - 如何在 UBUNTU 中使用 execl 函数删除文件

linux - 使用多宿主配置本地虚拟网络

c - 如何检查用户输入是否是 C 中的 float ?

关闭使用 shm_open() 打开的 FD(文件描述符),而不使用 close()?