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

进程 (一).fork(1)

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

前言

UNIX/Linux 是多任务的操作系统,那如何进行多任务处理呢,就是通过多个进程分别处理不同事务来实现

一颗单核CPU,在一个时刻里只能处理一条指令,所以在微观的世界里只可能有一个进程正在运行,那为什么是多任务的操作系统呢,那是由于操作系统将CPU时间分成很多的小时间片,并且将这些时间片分配给不同的任务,然后根据特定的方法在不同任务间进行快速的轮转(每一次切换任务都会对当前任务的进展进行保存,然后提取出下一个任务之前保存的进展,这个切换过程是有一定CPU开销的),而相对于计算机,人的速度非常慢,这样从宏观来看,给人的感觉就好像很多事务在同时推进一样,从而达到多任务或并行处理的效果,而多核的CPU就可以真实地进行并行处理,就好像多条流水线同时开工,在这里每个任务都可以看作是一个进程

这里分享一下我在学习进程过程中的笔记和心得


概要


代码示例

要求

将图中的流程图转换成程序

process.png
process.png

代码示例

代码语言:javascript
复制
#include <stdio.h>
#include <unistd.h> //fork,sleep,getpid,getppid 等函数的声明都在这个头文件里
#include <sys/wait.h> //waitpid, WNOHANG的函数声明和宏定义在这个头文件里

int main()
{
  pid_t pe; //定义一个pid类型的变量
  pe=fork(); //调用fork函数创建新进程,并将返回值存入pe变量中,这个过程成功后就会多出一个进程,被派生出来的进程称为子进程,pe也会多出一份拷贝,通过pe的值可以判断身处在哪一个之中
  if(0 < pe) //如果pe的值大于0,就代表为父进程,pe的值就是子进程的进程号
  {
    int pid,status;

    while (0 ==(pid = waitpid(-1,&status,WNOHANG)))sleep(1); //进行循环检测,如果子进程没有退出(waitpid的返回值为0就代表子进程还没有退出),就进行睡觉,睡觉1秒
    if(-1 !=  pid ) printf("this is the father process, my pid is %d, child process is %d, child exit status is: %d\n",getpid(),pe,WEXITSTATUS(status)); //正常情况下pid为正值,应为子进程的进程号,这时将pid,cpid和子进程的退出状态进行打印
    else perror("waitpid"); //如果为-1,那么就是出错,进行提醒
  }
  else if(0 == pe) //fork返回值为0的时候代表子进程
  {
    printf ("this is child, pid is :%d, my father pid is %d\n",getpid(),getppid()); //将pid,ppid进行打印
    sleep(5); //沉睡5秒
    return 123; //退出的状态码为123,这个值的范围在0~256
  }
  else //fork返回值为负的时候代表调用出错
  {
    perror("fork"); //进行提醒
    return -1;
  }

  return 0;
}

编译执行

代码语言:javascript
复制
emacs@ubuntu:~/c$ alias gtc
alias gtc='gcc -Wall -g -o'
emacs@ubuntu:~/c$ gtc forkprocess.x forkprocess.c 
emacs@ubuntu:~/c$ ./forkprocess.x 
this is child, pid is :7244, my father pid is 7243
this is the father process, my pid is 7243, child process is 7244, child exit status is: 123
emacs@ubuntu:~/c$ 

编译执行过程中没有报错,从结果来看,符合预期(当中有如预期一样的停顿,并且执行的先后顺序符合期望)


pid_t 的定义

在头文件中,我们通过层层追溯的方式可以找到一个类型的定义

这里我们来看看 pid_t 究竟是什么

代码语言:javascript
复制
emacs@ubuntu:/usr/include$ grep pid_t sys/types.h
#ifndef __pid_t_defined
typedef __pid_t pid_t;
# define __pid_t_defined
emacs@ubuntu:/usr/include$ grep include sys/types.h
#include <features.h>
#include <bits/types.h>
#include <time.h>
#include <stddef.h>
# include <endian.h>
# include <sys/select.h>
# include <sys/sysmacros.h>
# include <bits/pthreadtypes.h>
emacs@ubuntu:/usr/include$ grep pid_t bits/types.h
__STD_TYPE __PID_T_TYPE __pid_t;	/* Type of process identifications.  */
emacs@ubuntu:/usr/include$ grep include bits/types.h
 * Never include this file directly; use <sys/types.h> instead.
#include <features.h>
#include <bits/wordsize.h>
#include <bits/typesizes.h>	/* Defines __*_T_TYPE macros.  */
emacs@ubuntu:/usr/include$ grep __PID_T_TYPE bits/typesizes.h
#define __PID_T_TYPE		__S32_TYPE
emacs@ubuntu:/usr/include$ grep __S32_TYPE * -r 
bits/typesizes.h:#define __PID_T_TYPE		__S32_TYPE
bits/typesizes.h:#define __DADDR_T_TYPE		__S32_TYPE
bits/typesizes.h:#define __KEY_T_TYPE		__S32_TYPE
bits/typesizes.h:#define __CLOCKID_T_TYPE	__S32_TYPE
bits/types.h:#define	__S32_TYPE		int
emacs@ubuntu:/usr/include$ 

本文系转载,前往查看

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

本文系转载前往查看

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 概要
    • 代码示例
      • 要求
      • 代码示例
      • 编译执行
    • pid_t 的定义
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档