进程ID

1 进程id是唯一的。(不会有进程id一样的两个进程)

2进程id是可复用的,一个进程销毁后,它的id号可以被新的进程使用。但是Unix采用了延迟复用的算法,也就是进程   销毁后它的id不会立即被使用。

3 进程id为0的是调度进程。这是系统进程,是内核的一部分。

4 进程id为1的是init进程。init进程读取初始化文件/etc/rc*files 或者/etc/inittab,以及在/etc/init.d中的文件,使系统处于      某种状态。 init进程是用户进程,而不是系统进程。

进程id相关函数

  1. #include <unistd.h>
  2. pid_t getpid(void);
  3. Returns: process ID of calling process
  4. pid_t getppid(void);
  5. Returns: parent process ID of calling process
  6. uid_t getuid(void);
  7. Returns: real user ID of calling process
  8. uid_t geteuid(void);
  9. Returns: effective user ID of calling process
  10. gid_t getgid(void);
  11. Returns: real group ID of calling process
  12. gid_t getegid(void);
  13. Returns: effective group ID of calling process

创建新进程

#include <unistd.h>
pid_t fork(void);
Returns: 0 in child, process ID of child in parent,−1 on error
Unix可以使用系统函数fork()创建一个新进程。
    fork()执行一次返回两次。
    返回值:
        0: 
          表示子进程
        子进程id: 表示父进程
     子进程可以通过getppid()来获取父进程id,所以只需要返回0,表示创建成功即可.而对于父进程来说,他无从得知子进程的id,因此在创建的时候就应该吧子进程的Id号返回给他。

    我们知道,每个进程都会涉及到进程控制块、正文段、数据段,三部分内容。
    进程控制块是每个进程独有的,这就不用多说。 
    正文段里面是程序的指令,都是只读的,因此父进程和子进程可以共享这部分内容 。share
    数据段:  子进程会拷贝一份父进程的数据段(数据空间、堆、栈)。注意:这里是copy而不是share

    由于我们知道,一般创建子进程后,进阶着就是使用exec替换子进程为一个新的程序了,这是父进程的数据段内容就没什么用了。因此,现代系统在实现的时候,采用了写时复制copy-on-write(COW)。该方法就是内核将数据段设置为共享share,但它是只读的,当父进程或者子进程下需要对数据进行修改时,就自己copy一个副本。

    Example
#include "apue.h"
#include "myerr.h"
int globvar=6;/*external variable in initialized data */
char buf[] = "a write to stdout\n";
int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid;
var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
err_sys("write error");
printf("before fork\n"); /* we don’t flush stdout */
if ((pid = fork()) < 0) {
err_sys("fork error");
}else if (pid == 0) { /* child */
globvar++; /* modify variables */
var++;
}else {
sleep(2); /* parent */
}
printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
exit(0);
}
执行结果:
windeal@ubuntu:~/Windeal/apue$ ./exe
a write to stdout
before fork
pid = 4523, glob = 7, var = 89
pid = 4522, glob = 6, var = 88
windeal@ubuntu:~/Windeal/apue$

在这个例子中,我们在子进程中对globvar和var都进行自加,然后又在父进程中sleep(2),使得子进程先执行。
最终结果,父进程的数据都没变,子进程globvar和var都变成了新的值。
    从例子中可以看出,正文段是共享的,都使用了printf语句(你要说是copy,我就不跟你辩了。。。)
vfork()
    功能与fork()基本相似。

    不同点:
        vfork保证子进程先执行,也就是子进程执行了exec程序或者exit后才执行fork()。如果子进程中有依赖父进程的下一步动作才能执行的部分,可能会导致死锁。
        vfork创建的子进程会共享父进程的数据段。也就是说它会改变父进程的数据。
#include "apue.h"
#include "myerr.h"
int globvar=6;/*external variable in initialized data */
int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid;
var = 88;
printf("before vfork\n"); /* we don’t flush stdio */
if ((pid = vfork()) < 0) {
err_sys("vfork error");
}else if (pid == 0) { /* child */
globvar++; /* modify parent’s variables */
var++;
_exit(0); /* child terminates */
}
/* parent continues here */
printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
exit(0);
}

执行结果:
windeal@ubuntu:~/Windeal/apue$ ./exe
before vfork
pid = 6298, glob = 7, var = 89
windeal@ubuntu:~/Windeal/apue$

可以看到父进程globvar和var被子进程改变了。

        vfork()被一些版本视为过时的接口,一般不使用。所以不必过多研究,多用fork()来创建新进程即可。


APUE学习笔记——8.1-8.4 进程基础的更多相关文章

  1. apue学习笔记(第七章 进程环境)

    本章将了解进程的环境. main函数 C程序总是从main函数开始执行,main函数的原型是: int main(int argc,char *argv[]); 其中,argc是命令行参数的数目,ar ...

  2. APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause

    转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...

  3. APUE学习笔记3_文件IO

    APUE学习笔记3_文件IO Unix中的文件IO函数主要包括以下几个:open().read().write().lseek().close()等.这类I/O函数也被称为不带缓冲的I/O,标准I/O ...

  4. 大数据学习笔记——Java篇之网络编程基础

    Java网络编程学习笔记 1. 网络编程基础知识 1.1 网络分层图 网络分层分为两种模型:OSI模型以及TCP/IP网络模型,前者模型分为7层,是一个理论的,参考的模型:后者为实际应用的模型,具体对 ...

  5. [原创]java WEB学习笔记49:文件上传基础,基于表单的文件上传,使用fileuoload 组件

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  6. [学习笔记] 多项式与快速傅里叶变换(FFT)基础

    引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...

  7. C++学习笔记(一):C++基础知识

    一.C++基础知识 新的数据类型 C语言中的数据类型 C++中新的数据类型 思考:新的数据类型有什么好处?请看下面的代码: 可以见得:新的类型使整个程序更加简洁,程序变得易读易懂!这个就是bool类型 ...

  8. 数字图像处理学习笔记之一 DIP绪论与MATLAB基础

    写在前面的话 数字图像处理系列的学习笔记是作者结合上海大学计算机学院<数字图像处理>课程的学习所做的笔记,使用参考书籍为<冈萨雷斯数字图像处理(第二版)(MATLAB版)>,同 ...

  9. java学习笔记(1)java的基础介绍 、JDK下载、配置环境变量、运行java程序

    java工程师是开发软件的 什么是软件呢? 计算机包括两部分: 硬件: 鼠标.键盘.显示器.主机箱内部的cpu.内存条.硬盘等 软件: 软件包括:系统软件和应用软件 系统软件:直接和硬件交互的软件:w ...

随机推荐

  1. 【Python】模块

    廖雪峰教程笔记. [使用模块有什么好处?] 1.使用模块可以避免函数名和变量名冲突. 2.大大提高了代码的可维护性. [使用模块的注意点] 1.每一个.py文件就是一个模块. 2.每一个包目录下面必须 ...

  2. s3cmd安装

    配置yum.repos cd /etc/yum.repos.d/ vim s3tools.repo [s3tools] name=Tools for managing Amazon S3 - Simp ...

  3. Jquery12 Ajax

    学习要点: 1.Ajax 概述 2.load()方法 3.$.get()和$.post() 4.$.getScript()和$.getJSON() 5.$.ajax()方法 6.表单序列化 Ajax ...

  4. HBase安装过程

    1).上传,解压,重命名,修改环境变量/etc/profile 2).修改 hbase-env.sh 文件 export JAVA_HOME=/usr/java/jdk1.7.0_27 //Java ...

  5. mac下ssh到远程服务器时中文乱码

    前言:mac本地的语言环境为英文,远程是支持中文的, 问题: 一开始是在iterm2下登录远程服务器更新数据库时发现中文注释不能正常显示,以为是iterms2下设置有问题,使用系统自带的termina ...

  6. JAVA国际化输出日期格式

    1.建议控制台程序 使用 IntelliJ IDEA  创建 MAVEN项目, 不选别的选项,则为控制台程序. (其它方式创建的控制台程序可能编译不过) 2.源码如下: import java.tim ...

  7. PayPal2019春招实习生笔试题的某一题

    题目简单描述:给你n个点的坐标(x, y),均为浮点数. 如果任意两个点之间的欧几里得距离小于给定的一个浮点值,则认为这两个点之间有关联,并且关联具有传递性,总之就是尽可能扩大一个集合. 输入: d ...

  8. NOIP2014 T4 子矩阵 dfs+dp

    最近在狂补题啊QAQ... 打算先把NOIP的干掉吧... 点我看题 链接还是放洛谷的了... 题意:给一个n*m的矩阵,在这个矩阵里选 r 行 c 列,然后这 r 行 c 列所相交的格子为新矩阵的, ...

  9. jvm垃圾回收策略

    一.jvm堆内存的分代划分 在基于分代的内存回收策略中,堆空间通常都被划分为3个代,年轻代,年老代(或者tenured代),永久代.在年轻代中又被划分了三个小的区域,分别为:Eden(伊甸)区,S0区 ...

  10. C#错误的面试题

    你面试的时候是不是碰到这样的问题 String s = new String("xyz");创建了几个String Object? ,对于这个问题,我之前也一直以为是对的,这样写是 ...