我正在尝试分叉一个子进程让他进入睡眠状态并在用户输入一行文本时将其唤醒以打印输入的行数。
我的代码工作正常。但我发现奇怪的是我必须使用两个gets(str)语句,如果我没有提示用户只会被提示一次。
如果运行代码和评论得到(str)你会知道我的意思。
感谢您的帮助。感谢
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <wait.h>
#include <unistd.h>
#include <signal.h>
main () {
int n;
char ch;
pid_t child;
int erret;
char str[20];
int c = 0;
if ((child = fork ()) < 0) {
perror ("fork");
exit (0);
}
else {
//waitpid(child,NULL,0);
do {
waitpid (child, NULL, 0);
printf ("Enter a line(s) \n");
//funn();
//fflush(stdin);
//scanf("%d",&n);
gets (str);
gets (str);
erret = kill (child, SIGCHLD);
printf ("Signal %d\n", erret);
if (erret >= 0) {
c++;
printf ("You have entered : %d line(s)\n", c);
//pause();
//waitpid(child,NULL,0);
}
else {
kill (child, SIGKILL);
exit (0);
}
printf ("\nPress 9 to exit :");
fflush (stdin);
scanf ("%d", &n);
fflush (stdin);
} while (n != 9);
kill (child, SIGKILL);
}
}
答案 0 :(得分:1)
你的概念是有缺陷的,你没有明确指出父亲和孩子的所作所为。所以你在gets
上有种族条件。这是因为在fork
调用之后运行了两个代码副本,父代一个副本,子代表一个副本。因此,修复方法是添加swich
或else if
语句,将代码分隔为子级和父级的部分。 BTW已如上所述使用fgets
switch(fork()):
case -1:
//Error
case 0:
// Child code
default:
// Parant code
答案 1 :(得分:0)
您可以通过多种方式获得重复的字符串输入。标准方法之一是收集输入,直到用户发出信号EOF
表示没有更多数据要输入。 (在Linux上EOF
从终端生成ctrl + d
)。在不更改逻辑且未评论fork, waitpid, etc..
实施的情况下,以下是处理收集程序字符串输入的一种方法,直到用户通过按键盘上的EOF
发送ctrl+d
为止:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <wait.h>
#include <unistd.h>
#include <signal.h>
int main () {
pid_t child;
int erret;
int c = 0;
ssize_t nread = 0; /* number of chars read by getline */
char *lineptr = NULL; /* string read by (NULL forces getline to allocate) */
size_t nbytes = 0; /* number of bytes to read (ignored with lineptr = NULL) */
if ((child = fork ()) < 0) {
perror ("fork");
exit (0);
}
else
{
waitpid (child, NULL, 0);
printf ("\nEnter line(s) of text (ctrl+d to exit):\n\n");
while (printf (" Input: ") && (nread = getline (&lineptr, &nbytes, stdin) != -1))
{
erret = kill (child, SIGCHLD);
printf ("\n Signal %d\n", erret);
if (erret >= 0) {
c++;
printf (" You have entered : %d line(s)\n\n", c);
}
else
{
kill (child, SIGKILL);
exit (0);
}
}
kill (child, SIGKILL);
}
return 0;
}
<强>输出:强>
$ ./bin/ind2
Enter line(s) of text (ctrl+d to exit):
Input: line one
Signal 0
You have entered : 1 line(s)
Input: line 2
Signal 0
You have entered : 2 line(s)
Input: line 3
Signal 0
You have entered : 3 line(s)
Input: Killed