linux多进程

1. fork()创建进程,创建一份父进程的拷贝;在父进程中返回的是子进程id,在子进程中返回的是0;失败时返回-1;

2. fork()经常和exec()结合,exec() 覆盖了原进程的空间,转而执行其他程序;

3. 杀掉父进程,不会同时杀掉子进程;

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这个子进程称之为僵尸进程。系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程。孤儿进程并不会有什么危害。

当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大 量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了。

避免zombie的方法:

  • 忽略信号SIGCHLD, signal(SIGCHLD,SIG_IGN);
  • 父进程中调用wait或waitpid;
  • 调用两次fork();父进程一次fork()后产生一个子进程随后立即执行waitpid(子进程pid, NULL, 0)来等待子进程结束,然后子进程fork()后产生孙子进程随后立即exit(0)。这样子进程顺利终止(父进程仅仅给子进程收尸,并不需要子进程的返回值),然后父进程继续执行。这时的孙子进程由于失去了它的父进程(即是父进程的子进程),将被转交给Init进程托管。于是父进程与孙子进程无继承关系了,它们的父进程均为Init,Init进程在其子进程结束时会自动收尸,这样也就不会产生僵尸进程了。ddkkk
 #include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h> int main() {
pid_t pid; if ((pid = fork()) < ) {
fprintf(stderr,"Fork error!\n");
exit(-);
} else if (pid == ) { // child
if ((pid = fork()) < ) {
fprintf(stderr,"Fork error!\n");
exit(-);
} else if (pid > ) {
printf("child: %d, parent pid = %d\n", getpid(), getppid());
exit(); // child exit
} else {
printf("grandchild: %d, parent pid = %d\n", getpid(), getppid());
exit();
}
} else {
printf("pid: %d\n", getpid());
if (waitpid(pid, NULL, ) != pid) {
fprintf(stderr,"Waitpid error!\n");
exit(-);
}
return ;
}
}

输出为:

 root@xxj-VirtualBox:~/interview# ./process
pid:
child: , parent pid =
root@xxj-VirtualBox:~/interview# grandchild: , parent pid = root@xxj-VirtualBox:~/interview# ps ax|grep
? Ss : init --user
pts/ S+ : grep --color=auto

父进程是7411,子进程的父进程是7411没错,孙进程是7413,现在它被init进程(1755)回收了。

打印父进程的父进程发现是5976,5976是bash的pid。

4. wait() 等待子进程;可以获取子进程的返回状态;

5. system()就是用fork()+exec()+wait()实现;

6. execlp(),每一个是可执行文件的路径,第二个参数开始就是arg0,arg1,...,所以arg0必须就是可执行文件名,最后一个arg必须是NULL;

 int main() {
int pid = fork();
if (pid < ) {
fprintf(stderr, "fork failed");
return -;
} else if (pid == ) {
cout << "child process" << endl;
execlp("/bin/touch", "touch", "/root/lab/os/1", NULL);
} else {
cout << "pid of child:" << pid << endl;
int status;
wait(&status);
cout << "status of child:" << status << endl;
}
return ;
}

共享内存通信

1. shm_open打开或者创建共享内存object,名字必须以/开头;一开始大小为0;需要通过ftruncate()设置大小;

2. 用mmap将shared memory object映射到内存;映射为MAP_SHARED,这样在其他进程中可见;即使进程退出了,在没有调用shm_unlink之前,其他进程还是可以访问这一块区域的。

 #include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h> int main() {
int shmID = shm_open("/test", O_CREAT | O_RDWR, );
if (shmID < ) {
fprintf(stderr, "shm create failed\n");
return -;
}
ftruncate(shmID, );
char* p = (char*)mmap(NULL, , PROT_WRITE, MAP_SHARED, shmID, );
for (int i = ; i < ; i++) {
p[i] = '' + i % ;
}
munmap(p, );
return ;
}
 #include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h> int main() {
int shmID = shm_open("/test", O_RDONLY, );
if (shmID < ) {
fprintf(stderr, "shm open fail\n");
return -;
}
char* p = (char*)mmap(NULL, , PROT_READ, MAP_SHARED, shmID, );
if (p == NULL) {
return -;
}
for (int i = ; i < ; i++) {
printf("%c ", p[i]);
}
printf("\n"); shm_unlink("/test");
munmap(p, );
return ;
}

OS | Process的更多相关文章

  1. android.os.Process.killProcess(android.os.Process.myPid())与Activity生命周期的影响

    如果通过finish方法结束了一个Activity,那么根据Activity的生命周期,则会自动调用Activity的销毁方法onDestory(),但是在项目中遇到这样的一个问题,就是​Activi ...

  2. Android :android.os.Process.myTid()与 Thread.currentThread().getId();

    这两种方式得到的ID并不是相同的,前者的返回值是int,后者是long. 个人猜测:应该是一个线程的两种得到的方式.类似于一个人有2个名字. 如有不对,请指正!

  3. A discussion of Dead Connection Detection, Resource Limits, V$SESSION, V$PROCESS and OS processes

    A discussion of Dead Connection Detection, Resource Limits, V$SESSION, V$PROCESS and OS processes (文 ...

  4. Node.js & process.env & OS Platform checker

    Node.js & process.env & OS Platform checker Window 10 Windows 7 ia32 CentOS $ node # process ...

  5. golang os/exec 执行外部命令

    exec包执行外部命令,它将os.StartProcess进行包装使得它更容易映射到stdin和stdout,并且利用pipe连接i/o. func LookPath(file string) (st ...

  6. [Java][Android][Process] 暴力的服务能够解决一切,暴力的方式运行命令行语句

    不管是在Java或者Android中运行命令行语句殊途同归都是创建一个子进程运行调用可运行文件运行命令.类似于Windows中的CMD一样. 此时你有两种方式运行:ProcessBuilder与Run ...

  7. [Java][Android][Process] ProcessBuilder与Runtime差别

    在Android中想要进行Ping,在不Root机器的情况下似乎还仅仅能进行底层命调用才干实现. 由于在Java中要进行ICMP包发送须要Root权限. 于是仅仅能通过创建进程来攻克了.创建进程在Ja ...

  8. [Java][Android][Process] 分享 Process 运行命令行封装类型

    我在以前的文章中提到,使用Java不会有一个问题,创建运行命令来创建太多进程后创建进程行语句. [Android] ProcessBuilder与Runtime.getRuntime().exec分别 ...

  9. [20190416]process allocation latch.txt

    [20190416]process allocation latch.txt --//看链接:http://andreynikolaev.wordpress.com/2010/12/16/hidden ...

随机推荐

  1. Python中类的声明,使用,属性,实例属性,计算属性及继承,重写

    Python中的类的定义以及使用: 类的定义: 定义类 在Python中,类的定义使用class关键字来实现 语法如下: class className: "类的注释" 类的实体 ...

  2. [译]The Python Tutorial#4. More Control Flow Tools

    [译]The Python Tutorial#More Control Flow Tools 除了刚才介绍的while语句之外,Python也从其他语言借鉴了其他流程控制语句,并做了相应改变. 4.1 ...

  3. 04 Django模板

    基本概念 作为Web框架,Django提供了模板,用于编写html代码,还可以嵌入模板代码更快更方便的完成页面开发,再通过在视图中渲染模板,将生成最终的html字符串返回给客户端浏览器 模版致力于表达 ...

  4. 学习ucosii要用到的几本书

    转自:http://bbs.elecfans.com/jishu_551275_1_1.html   1.嵌入式实时操作系统μC/OS-II(第2版)  邵贝贝 等译 北京航空航天大学出版社     ...

  5. Servlet注意事项

    注意事项 1.对于Servlet的应用程序的目录结构来说,若想让有些文件Servlet可以访问,而用户不能访问的时候,可以将其放置在WEB-INF目录下 2.ServletResponse中getwr ...

  6. debian使用ibus

    $ sudo apt-get install ibus ibus-pinyin 点击右上角的键盘图标,设置拼音输入法

  7. hdu4489 组合公式+dp

    这里对于题意在说明一下, 题目中要求的排列必须是波浪形,每一个在排列中的人不是波峰就是波谷,如果它既不是波峰也不是波谷排列就是错的. 对于我这种数学渣渣来说,做一道dp题要好久,%>_<% ...

  8. BZOJ 5334: [Tjoi2018]数学计算

    线段树裸题 难度在于认识到这个没法线性做 #include<cstdio> using namespace std; int n,mod,tr[400005]; void insert(i ...

  9. jcenter maven 库

    先了解compile ‘com.squareup.okhttp:okhttp:2.4.0’的意义 首先我们要了解compile ‘com.squareup.okhttp:okhttp:2.4.0’这一 ...

  10. 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索

    题目描述 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策 ...