免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2296 | 回复: 7
打印 上一主题 下一主题

[函数] 关于子父子进程的一个非常有趣的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-29 23:12 |只看该作者 |倒序浏览
大家好,大家请看下面的代码,注意红色字体部分,为什么这里会等待父进程呢?
#include "apue.h"
#include <errno.h>

static void
sig_hup(int signo)
{
    printf("SIGHUP received, pid = %d\n", getpid());
}

static void
pr_ids(char *name)
{
    printf("%s: pid = %d, ppid = %d, pgrp = %d, tpgrp = %d\n",
        name, getpid(), getppid(), getpgrp(), tcgetpgrp(STDIN_FILENO));
    fflush(stdout);
}

int
main(void)
{
     char     c;
     pid_t    pid;

     pr_ids("parent");
     if ((pid = fork()) < 0) {
         printf("fork error");
     } else if (pid > 0) {   /* parent */
         sleep(5);       /*sleep to let child stop itself */
         exit(0);        /* then parent exits */
     } else {            /* child */
         pr_ids("child");
         signal(SIGHUP, sig_hup);    /* establish signal handler */

         pr_ids("child");    /* prints only if we're continued */
         if (read(STDIN_FILENO, &c, 1) != 1)
             printf("read error from controlling TTY, errno = %d\n",
                 errno);
         else
             printf("read from controlling TTY successful!\n");
         
         printf("the child process exit!\n");
         exit(0);
     }
}

输出为:
parent: pid = 3838, ppid = 2985, pgrp = 3838, tpgrp = 3838
child: pid = 3839, ppid = 3838, pgrp = 3838, tpgrp = 3838
child: pid = 3839, ppid = 3838, pgrp = 3838, tpgrp = 3838                (输出到这条时稍微停了一会儿,在等待父进程)
[root@localhost orphaned]# read from controlling TTY successful!     (只输出[root@localhost orphaned]# ,按回车后才输出后面的内容和下一行)
the child process exit!

由输出可以看出,程序运行到红色字体后,子进程等待父进程,直到父进程sleep完。然后我试过把红色字体换成
if(1)
   printf("read error from controlling TTY, errno = %d\n",errno);
这样子子进程就会直接跑完,而不等父进程了,这说明了read(STDIN_FILENO, &c, 1)这个函数会导致子进程等待父进程。我的问题就是为什么会导致子进程等待父进程呢?
百思不得其解,只好来请教大家,非常感谢!!!

论坛徽章:
0
2 [报告]
发表于 2008-07-29 23:13 |只看该作者
附apue.h:
/* Our own header, to be included before all standard system headers */

#ifndef _APUE_H
#define _APUE_H

#define _XOPEN_SOURCE   600  /* Single UNIX Specification, Version 3 */

#include <sys/types.h>       /* some systems still require this */
#include <sys/stat.h>
#include <sys/termios.h>     /* for winsize */
#ifndef TIOCGWINSZ
#include <sys/ioctl.h>
#endif
#include <stdio.h>     /* for convenience */
#include <stdlib.h>    /* for convenience */
#include <stddef.h>    /* for offsetof */
#include <string.h>    /* for convenience */
#include <unistd.h>    /* for convenience */
#include <signal.h>    /* for SIG_ERR */


#define MAXLINE 4096               /* max line length */

/*
* Default file access permissions for new files.
*/
#define FILE_MODE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

/*
* Default permissions for new directories.
*/
#define DIR_MODE    (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)

typedef void   Sigfunc(int);   /* for signal handlers */

#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((Sigfunc *)-1)
#endif

#define min(a,b)     ((a) < (b) ? (a) : (b))
#define max(a,b)     ((a) > (b) ? (a) : (b))

/*
* Prototypes for our own functions.
*/
char    *path_alloc(int *);              /* Figure 2.15 */
long     open_max(void);                 /* Figure 2.16 */
void     clr_fl(int, int);               /* Figure 3.11 */
void     set_fl(int, int);               /* Figure 3.11 */
void     pr_exit(int);                   /* Figure 8.5 */
void     pr_mask(const char *);          /* Figure 10.14 */
Sigfunc *signal_intr(int, Sigfunc *);    /* Figure 10.19 */

int      tty_cbreak(int);                /* Figure 18.20 */
int      tty_raw(int);                   /* Figure 18.20 */
int      tty_reset(int);                 /* Figure 18.20 */
void     tty_atexit(void);               /* Figure 18.20 */
#ifdef  ECHO    /* only if <termios.h>  has been included */
struct termios  *tty_termios(void);      /* Figure 18.20 */
#endif

void     sleep_us(unsigned int);             /* Exercise 14.6 */
ssize_t  readn(int, void *, size_t);         /* Figure 14.29 */
ssize_t  writen(int, const void *, size_t);  /* Figure 14.29 */
void     daemonize(const char *);            /* Figure 13.1 */

int      s_pipe(int *);                 /* Figures 17.6 and 17.13 */
int      recv_fd(int, ssize_t (*func)(int,
                 const void *, size_t));/* Figures 17.21 and 17.23 */
int      send_fd(int, int);             /* Figures 17.20 and 17.22 */
int      send_err(int, int,
                  const char *);        /* Figure 17.19 */
int      serv_listen(const char *);     /* Figures 17.10 and 17.15 */
int      serv_accept(int, uid_t *);     /* Figures 17.11 and 17.16 */

int      cli_conn(const char *);        /* Figures 17.12 and 17.17 */
int      buf_args(char *, int (*func)(int,
                  char **));            /* Figure 17.32 */

int      ptym_open(char *, int);    /* Figures 19.8, 19.9, and 19.10 */
int      ptys_open(char *);         /* Figures 19.8, 19.9, and 19.10 */
#ifdef  TIOCGWINSZ
pid_t    pty_fork(int *, char *, int, const struct termios *,
                  const struct winsize *);      /* Figure 19.11 */
#endif

int     lock_reg(int, int, int, off_t, int, off_t); /* Figure 14.5 */
#define read_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len))
#define readw_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len))
#define write_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len))
#define writew_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))
#define un_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))

pid_t   lock_test(int, int, off_t, int, off_t);     /* Figure 14.6 */

#define is_read_lockable(fd, offset, whence, len) \
            (lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0)
#define is_write_lockable(fd, offset, whence, len) \
            (lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0)

void    err_dump(const char *, ...);        /* Appendix B */
void    err_msg(const char *, ...);
void    err_quit(const char *, ...);
void    err_exit(int, const char *, ...);
void    err_ret(const char *, ...);
void    err_sys(const char *, ...);

void    log_msg(const char *, ...);         /* Appendix B */
void    log_open(const char *, int, int);
void    log_quit(const char *, ...);
void    log_ret(const char *, ...);
void    log_sys(const char *, ...);

void    TELL_WAIT(void);        /* parent/child from Section 8.9 */
void    TELL_PARENT(pid_t);
void    TELL_CHILD(pid_t);
void    WAIT_PARENT(void);
void    WAIT_CHILD(void);

#endif  /* _APUE_H */

论坛徽章:
0
3 [报告]
发表于 2008-07-29 23:25 |只看该作者
子进程不是在等待父进程,而是在等待你输入一个字符

论坛徽章:
52
码神
日期:2017-03-28 10:27:10综合交流区版块每日发帖之星
日期:2015-10-11 06:20:00综合交流区版块每日发帖之星
日期:2015-09-28 06:20:00综合交流区版块每日发帖之星
日期:2015-09-22 06:20:00每日论坛发贴之星
日期:2015-09-12 06:20:00综合交流区版块每日发帖之星
日期:2015-09-12 06:20:00综合交流区版块每日发帖之星
日期:2015-09-08 06:20:00综合交流区版块每日发帖之星
日期:2015-09-05 06:20:00综合交流区版块每日发帖之星
日期:2015-09-04 06:20:002015亚冠之德黑兰石油
日期:2015-09-01 10:41:53每日论坛发贴之星
日期:2015-10-11 06:20:00综合交流区版块每日发帖之星
日期:2015-10-12 06:20:00
4 [报告]
发表于 2008-07-29 23:31 |只看该作者

回复 #1 huangbt_unix 的帖子

不懂。。。

论坛徽章:
0
5 [报告]
发表于 2008-07-29 23:49 |只看该作者
read(STDIN_FILENO, &c, 1)
这句的意思是从标准输入读入一个字符,如果我没有理解错的话

论坛徽章:
0
6 [报告]
发表于 2008-07-30 00:03 |只看该作者
父子进程间
如果是未指定wait( 即未确定的让父进程阻塞),
那么它们的执行顺序是不确定的

论坛徽章:
0
7 [报告]
发表于 2008-07-30 07:48 |只看该作者
同意3楼和6楼

论坛徽章:
0
8 [报告]
发表于 2008-07-30 08:36 |只看该作者
哎,我懂了,多谢大家啊!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP