两个参数的简单shell程序(并发问题)

时间:2019-02-02 13:09:04

标签: shell input concurrency fork

我试图完成它由在模拟一个简单的外壳程序,即只获得2个参数的分配,并将其顺序地或同时地运行,取决于用户输入。

尽管,我很难实现并发版本,因为当我输入sleep 1 &输入(安培表示并发)时,父级不会按预期等待子级,而是继续迭代,但是在进行readSplit函数的while循环的第二次迭代时,与其暂停程序等待用户输入,不如将空白buff作为输入。

尽管如此,如果我编写sleep 1ls或任何只需要2个参数的命令,它就可以正常工作。

一些说明:

-readSplit仅获得用户的输入。它的功能类似于read()函数,但是到达分隔符后将停止读取。 (我知道有一个更好的功能可以做到这一点,但是该代码是由课程提供的。)

int readSplit( int fin, char* buff, char* s, int maxlen ) {
   int i = 0;
   int oneread = 1;
   char c = *s+1;
   while(c != *s && c != '\n' && oneread == 1 && i < maxlen) {
       oneread = read( fin, &c, 1);
       if(c != *s && c != '\n' && oneread == 1) {
              buff[i] = c;
           i++;
       }
   }
   if(c=='\n') *s = c;
   if(i < maxlen) buff[i] = '\0';
   return i;
}

- startTimerendTimer可以忽略,他们只是测量的执行时间

主要代码:

#include <sys/types.h> /* pid_t */
#include <sys/wait.h>  /* waitpid */
#include <sys/types.h> /* pid_t */
#include <sys/wait.h>  /* waitpid */
#include <stdio.h>     /* printf, perror */
#include <stdlib.h>    /* exit */
#include <unistd.h>    /* _exit, fork */
#include <string.h>
#include "myutils.h"

int main(void) {
   int ret;
   int status;
   char buff[80];
   char buff_aux[80];
   char ampersan[1];
   long timer;
   int continueloop = 1;

while (continueloop == 1) {

    char s = ' '; //Separator
    /*Cleaning the information in each loop*/


    memset(buff, 0, sizeof (buff));
    memset(buff_aux, 0, sizeof (buff_aux));
    memset(ampersan, 0, sizeof (ampersan));
    write(1, ">", 1);
    /*Reading user input*/

        readSplit(0, buff, &s, 80);
        printf("%s its my buff string\n", buff);

    if (strcmp(buff, "exit") == 0)break; //If the user wants to exit


    /*If the user has one more parameter we read it and put it in the buff_aux*/
    if (s == ' ' ) {
        if (readSplit(0, buff_aux, &s, 80) == 0)
            exit(1);
    }
    printf("%s is my buff_aux string\n", buff_aux);

    if (s == ' ' ) {
        readSplit(0, ampersan, &s, 1);
        printf("%c is the letter read by ampersan\n", ampersan[0]);

    }
    startTimer();
    /*Creating child*/
    ret = fork();
    printf("ret %d\n", ret);
    printf("im checking if it is a child\n");
    if (ret == 0) {
        printf("im a child\n");
        if (buff[0] == 0) {
            printf("Son: shell program does not exist\n");
            exit(255);
        } else if (buff_aux[0] == 0 || buff_aux[0] == '&') {
            printf("Im about to execute 1\n");
            execlp(buff, buff, NULL);
            exit(2);
        } else {
            printf("Im about to execute 2\n");
            execlp(buff, buff, buff_aux, NULL);
            exit(2);

        }
    }
    if (ampersan[0] != '&') {
        wait(NULL);
        timer = endTimer();
        printf("The process finished and lasted ... %li miliseconds\n", timer);
    }


}
/*waiting to children to finish*/
while (wait(NULL) > 0);
timer=endTimer();

printf("Father waited for son\n");
if (WIFEXITED(status)) {
    status = WEXITSTATUS(status);
    if (status > 0) printf("Father: shell program does not exist\n");
}

return 0;
}

提前谢谢!

1 个答案:

答案 0 :(得分:0)

如果您输入sleep 1 &,则输入缓冲区为sleep 1 &\n

第一次:

  1. 呼叫readSplit(0, buff, &s, 80);buffsleep,输入缓冲区剩余1 &\n
  2. 呼叫readSplit(0, buff_aux, &s, 80)buffer_aux1,输入缓冲区剩余&\n
  3. 呼叫readSplit(0, ampersan, &s, 1); ampersan&,输入缓冲区剩余\n

下一个:

输入缓冲区剩余\n

  1. 调用readSplit(0, buff, &s, 80);buff为空,c为\n,在子进程中将调用:
if (buff[0] == 0) {
   printf("Son: shell program does not exist\n");
   exit(255);
}

您应该在每个\n中处理while