等待来自 parent 的信号并再次执行作业和阻塞
Wait for signal from parent and does job and blocks again
编写一个程序,可以显示一个文本字符串(仅由 26 个字母和空格组成)。该程序应分叉 27 个工作进程。每个工作进程运行一个无限循环,等待来自控制器的信号(即 parent),休眠 1 秒,打印其 pre-defined 字符,向控制器发出信号,然后再次阻塞。控制器从键盘读取一个字符串,然后以正确的顺序向工作人员发出信号以显示该字符串
以下是我的代码,但我没有得到输出,它没有打印任何东西。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <string.h>
int
main()
{
/*...declarations and stuff....*/
scanf("%s",inputString);
length=strlen(inputString);
for (i=0;i<27;i++)
{
pid[i]=fork();
if (pid[i]==0)
{
/*...Declare my character...*/
while (1)
{
pause();
sleep(1);
printf("%c",myChar);
kill(ppid,SIGCONT);
}
return 0;
}
}
for (i=0;i<length;i++)
{
int temp=inputString[i];
if (temp==32)
{
kill(pid[0],SIGCONT);
}
else
{
kill(pid[temp-96],SIGCONT);
}
pause();
}
for(i=0;i<27;i++)
kill(pid[i],SIGTERM);
return 0;
}
首先不要使用 SIGCONT
或其他类似的信号进行自定义使用。更喜欢使用 SIGUSR1
和 SIGUSR2
。 SIGCONT
有一些特殊的语义。
现在即使您将 CONT
更改为 USR1
,您使用 pause()
的方式也是一个问题。 child 进程被唤醒后,它会被杀死,因为你没有捕捉到信号。手册说:
pause()
causes the calling process (or thread) to sleep until a
signal is delivered that either terminates the process or causes the
invocation of a signal-catching function.
Children 永远不会发出正确的信号,因为您没有将 ppid
设置为正确的值。
您永远不会正确地体验打印,因为写入是缓冲的并且没有刷新。使用 printf("%c",myChar); fflush(stdout);
或 printf("%c\n",myChar);
这将导致类似的结果:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <string.h>
void handler(int sig) {
}
int main() {
pid_t ppid;
int length;
char inputString[256];
pid_t pid[256];
int i;
char myChar;
scanf("%s",inputString);
length=strlen(inputString);
struct sigaction action;
sigemptyset(&(action.sa_mask));
action.sa_flags = 0;
action.sa_handler = handler;
sigaction(SIGUSR1,&action,NULL);
ppid = getpid();
for (i=0;i<27;i++) {
pid[i]=fork();
if (pid[i]==0) {
myChar='a'+i;
while (1) {
pause();
sleep(1);
printf("%c\n",myChar);
kill(ppid,SIGUSR1);
}
return 0;
}
}
for (i=0;i<length;i++) {
int temp=inputString[i];
if (temp==32) {
kill(pid[0],SIGUSR1);
}
else {
kill(pid[temp-'a'],SIGUSR1);
}
pause();
}
for(i=0;i<27;i++)
kill(pid[i],SIGTERM);
return 0;
}
- 没什么好说的,比如为什么要循环27?等,其实都是些小问题(不是说以后不改) .
编写一个程序,可以显示一个文本字符串(仅由 26 个字母和空格组成)。该程序应分叉 27 个工作进程。每个工作进程运行一个无限循环,等待来自控制器的信号(即 parent),休眠 1 秒,打印其 pre-defined 字符,向控制器发出信号,然后再次阻塞。控制器从键盘读取一个字符串,然后以正确的顺序向工作人员发出信号以显示该字符串 以下是我的代码,但我没有得到输出,它没有打印任何东西。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <string.h>
int
main()
{
/*...declarations and stuff....*/
scanf("%s",inputString);
length=strlen(inputString);
for (i=0;i<27;i++)
{
pid[i]=fork();
if (pid[i]==0)
{
/*...Declare my character...*/
while (1)
{
pause();
sleep(1);
printf("%c",myChar);
kill(ppid,SIGCONT);
}
return 0;
}
}
for (i=0;i<length;i++)
{
int temp=inputString[i];
if (temp==32)
{
kill(pid[0],SIGCONT);
}
else
{
kill(pid[temp-96],SIGCONT);
}
pause();
}
for(i=0;i<27;i++)
kill(pid[i],SIGTERM);
return 0;
}
首先不要使用
SIGCONT
或其他类似的信号进行自定义使用。更喜欢使用SIGUSR1
和SIGUSR2
。SIGCONT
有一些特殊的语义。现在即使您将
CONT
更改为USR1
,您使用pause()
的方式也是一个问题。 child 进程被唤醒后,它会被杀死,因为你没有捕捉到信号。手册说:
pause()
causes the calling process (or thread) to sleep until a signal is delivered that either terminates the process or causes the invocation of a signal-catching function.
Children 永远不会发出正确的信号,因为您没有将
ppid
设置为正确的值。您永远不会正确地体验打印,因为写入是缓冲的并且没有刷新。使用
printf("%c",myChar); fflush(stdout);
或printf("%c\n",myChar);
这将导致类似的结果:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <string.h>
void handler(int sig) {
}
int main() {
pid_t ppid;
int length;
char inputString[256];
pid_t pid[256];
int i;
char myChar;
scanf("%s",inputString);
length=strlen(inputString);
struct sigaction action;
sigemptyset(&(action.sa_mask));
action.sa_flags = 0;
action.sa_handler = handler;
sigaction(SIGUSR1,&action,NULL);
ppid = getpid();
for (i=0;i<27;i++) {
pid[i]=fork();
if (pid[i]==0) {
myChar='a'+i;
while (1) {
pause();
sleep(1);
printf("%c\n",myChar);
kill(ppid,SIGUSR1);
}
return 0;
}
}
for (i=0;i<length;i++) {
int temp=inputString[i];
if (temp==32) {
kill(pid[0],SIGUSR1);
}
else {
kill(pid[temp-'a'],SIGUSR1);
}
pause();
}
for(i=0;i<27;i++)
kill(pid[i],SIGTERM);
return 0;
}
- 没什么好说的,比如为什么要循环27?等,其实都是些小问题(不是说以后不改) .