前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >进程 (一).fork(2)

进程 (一).fork(2)

作者头像
franket
发布2021-09-16 09:46:42
6930
发布2021-09-16 09:46:42
举报
文章被收录于专栏:技术杂记技术杂记

从中可知整个定义链是这样的

pid_t=>__pid_t=>__PID_T_TYPE=>__S32_TYPE=>int

pid_t 实际上就是 int

那也就意味着可以直接使用int类型来替代 pid_t ,只是使用 pid_t 会更直观


fork,sleep,getpid,getppid 原型

unistd.h 中包含 fork,sleep,getpid,getppid 的函数原型

代码语言:javascript
复制
/* Clone the calling process, creating an exact copy.
   Return -1 for errors, 0 to the new process,
   and the process ID of the new process to the old process.  */
extern __pid_t fork (void) __THROW;
/* Make the process sleep for SECONDS seconds, or until a signal arrives
   and is not ignored.  The function returns the number of seconds less
   than SECONDS which it actually slept (thus zero if it slept the full time).
   If a signal handler does a `longjmp' or modifies the handling of the
   SIGALRM signal while inside `sleep' call, the handling of the SIGALRM
   signal afterwards is undefined.  There is no return value to indicate
   error, but if `sleep' returns SECONDS, it probably didn't work.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern unsigned int sleep (unsigned int __seconds);
/* Get the process ID of the calling process.  */
extern __pid_t getpid (void) __THROW;

/* Get the process ID of the calling process's parent.  */
extern __pid_t getppid (void) __THROW;

fork 和 vfork

unistd.h 中包含 fork,vfork 的函数原型

代码语言:javascript
复制
/* Clone the calling process, creating an exact copy.
   Return -1 for errors, 0 to the new process,
   and the process ID of the new process to the old process.  */
extern __pid_t fork (void) __THROW;
/* Clone the calling process, but without copying the whole address space.
   The calling process is suspended until the new process exits or is
   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
   and the process ID of the new process to the old process.  */
extern __pid_t vfork (void) __THROW;

它们都是克隆一份主调进程,如果成功就返回子进程的进程ID给父进程,返回0给子进程,出错就返回-1

区别是在内存中vfork是进行COW(写时复制)的,fork是全部拷贝,因此vfork速度会更快,更省空间


wait,waitpid

代码语言:javascript
复制
/* Wait for a child to die.  When one does, put its status in *STAT_LOC
   and return its process ID.  For errors, return (pid_t) -1.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern __pid_t wait (__WAIT_STATUS __stat_loc);
/* Wait for a child matching PID to die.
   If PID is greater than 0, match any process whose process ID is PID.
   If PID is (pid_t) -1, match any process.
   If PID is (pid_t) 0, match any process with the
   same process group as the current process.
   If PID is less than -1, match any process whose
   process group is the absolute value of PID.
   If the WNOHANG bit is set in OPTIONS, and that child
   is not already dead, return (pid_t) 0.  If successful,
   return PID and store the dead child's status in STAT_LOC.
   Return (pid_t) -1 for errors.  If the WUNTRACED bit is
   set in OPTIONS, return status for stopped children; otherwise don't.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern __pid_t waitpid (__pid_t __pid, int *__stat_loc, int __options);

从上面的描述可以知道

wait(&status) 相当于 waitpid(-1,&status,0)

实际上Linux 内部在实现wait函数时直接调用的就是waitpid函数

status 是用来存放返回值的,一般不是直接使用,而是通过宏来进行解析,例如 WEXITSTATUS(status)

stdlib.h 头文件中有如下定义

代码语言:javascript
复制
/* Define the macros <sys/wait.h> also would define this way.  */
# define WEXITSTATUS(status)    __WEXITSTATUS (__WAIT_INT (status))
# define WTERMSIG(status)       __WTERMSIG (__WAIT_INT (status))
# define WSTOPSIG(status)       __WSTOPSIG (__WAIT_INT (status))
# define WIFEXITED(status)      __WIFEXITED (__WAIT_INT (status))
# define WIFSIGNALED(status)    __WIFSIGNALED (__WAIT_INT (status))
# define WIFSTOPPED(status)     __WIFSTOPPED (__WAIT_INT (status))

WNOHANG

linux/wait.h

代码语言:javascript
复制
#ifndef _LINUX_WAIT_H
#define _LINUX_WAIT_H

#define WNOHANG         0x00000001
#define WUNTRACED       0x00000002
#define WSTOPPED        WUNTRACED
#define WEXITED         0x00000004
#define WCONTINUED      0x00000008
#define WNOWAIT         0x01000000      /* Don't reap, just poll status.  */

#define __WNOTHREAD     0x20000000      /* Don't wait on children of other threads in this group */
#define __WALL          0x40000000      /* Wait on all children, regardless of type */
#define __WCLONE        0x80000000      /* Wait only on non-SIGCHLD children */

/* First argument to waitid: */
#define P_ALL           0
#define P_PID           1
#define P_PGID          2


#endif

waitpid的参数options是一个或多个标致符按位“或”的结果


总结

以下这些函数可以进行进程创建和简单的管理

  • fork
  • waitpid/wait

通过各方面资料弄懂其参数的意义和返回值的类型,是熟练掌握的基础

原文地址http://soft.dog/2017/01/09/c-fork-01/

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • fork,sleep,getpid,getppid 原型
  • fork 和 vfork
  • wait,waitpid
  • WNOHANG
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档