如何才能用C执行子进程(How to execute child processes in orde

2019-10-19 02:04发布

我已经写在C代码计算行字和字符在文件中。 像wc命令。 代码如下表和工作正常。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

char* concat(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);
strcpy(result, s1);
strcat(result, s2);
return result;
} 

int countLines(char *f){
 FILE *file = fopen(f, "r");
int count = 0;
char ch;
while ((ch = fgetc(file)) != EOF){
   if (ch == '\n')
       count++;
}
return count;
}

int countWords(char *f){
char buffer[1];
FILE *file = fopen(f, "r");
  int countW = 0;
  enum states { WSP, WRD };
  int state = WSP;
char last = ' '; 
 while (read(fileno(file),buffer,1) == 1 )
 {
 if ( buffer[0]== ' ' || buffer[0] == '\t' || buffer[0]=='\n' )
 {
    state = WSP;
 }
 else 
 {
    if ( state == WSP )
    {
       countW++;
    }
    state = WRD;
 }
  last = buffer[0];
}
return countW;
}

int countChars(char *f){
 FILE *file = fopen(f, "r");
int chars = 0;
char ch;
while ((ch = fgetc(file))){
     if (ch == EOF) break;
  chars++;
}
return chars;
}

int main(int argc, char** argv)
{
 int lineCount = 0;
 int wordCount = 0;
 int charCount = 0;
 int n = 3;
 int i,status;
 int pids[3];
 char *theprogram = argv[0];
 char *thefile = argv[1];
 if ( argc !=2 )
 {
     printf( "Help: %s filename\n", argv[0]);
 }
 else{
     FILE *file = fopen( argv[1], "r");

   if(file == 0){
         char *sub = concat(theprogram, ": ");
         char *middle = concat(sub, thefile); 
         perror(middle);
   }
   else{
         for (i = 0; i < n; i++) {
             pids[i] = fork();
             if ( pids[i] < 0) { 
                perror("fork"); 
                exit(-1); 
            } else if (pids[i] == 0) { 
                if (i==0){
                        lineCount = countLines(argv[1]);
                        printf("This is child proccess %d, and the number of lines is %d\n", i+1, lineCount);
                        exit(0);
                    }
                    else if (i==1){ 
                        wordCount = countWords(argv[1]);
                        printf("This is child proccess %d, and the number of words is %d\n", i+1, wordCount);
                        exit(0);
                    }
                    else if (i==2){
                        charCount += countChars(argv[1]);
                        printf("This is child proccess %d, and the number of characters is %d\n", i+1, charCount);
                        exit(0);
                    }
            } 
          }
            for(i = 0; i < n; i++){
                wait(NULL);
            }
            return 0;      
            }
 } 
}

我的问题是这样的:

输出并不总是按顺序是这样的:

//GOOD
This is child proccess 1, and the number of lines is 5
This is child proccess 2, and the number of words is 5
This is child proccess 3, and the number of characters is 159

//BAD
This is child proccess 1, and the number of lines is 5
This is child proccess 3, and the number of characters is 159
This is child proccess 2, and the number of words is 5

第三处理前的第二有时结束。 我该如何避免这种情况?

Answer 1:

快速和肮脏的方法:

        } else if (pids[i] == 0) { 
            usleep(i*1000);  /* wait 1ms for child 1, 2ms for child 2,... */
            if (i==0){
                    lineCount = countLines(argv[1]);
                    printf("This is child proccess %d, and the number of lines is %d\n", i+1, lineCount);
                    exit(0);
                }
                else if (i==1){ 
                    wordCount = countWords(argv[1]);
                    printf("This is child proccess %d, and the number of words is %d\n", i+1, wordCount);
                    exit(0);
                }
                else if (i==2){
                    charCount += countChars(argv[1]);
                    printf("This is child proccess %d, and the number of characters is %d\n", i+1, charCount);
                    exit(0);
                }
        } 

另一种方式是通过让父进程创建三个Unix套接字,并使用倾听他们都select()或类似的东西。 蔡尔兹将连接并写入套接字,退出,然后,父进程将打印在正确顺序接收的信息。



Answer 2:

分叉进程将异步执行为主线的代码,所以如果你想他们为了发生,你需要用某种标志。 这可能是一个信号,互斥,或设置条件语句,如果里面一个布尔值。

你可能会需要使用旗语或互斥体,以保护异步写入数据敏感,但是这不是在这方面的问题。



Answer 3:

我认为ü可以使用线程,但没有过程,初始化一些全局变量,并在指定的子线程中的变量值。 控制父线程的输出。



文章来源: How to execute child processes in order in C
标签: c process fork