转:http://www.cnblogs.com/GT_Andy/archive/2011/06/21/2086129.html
我们都知道,进程就是正在执行的程序。而在Linux中,可以使用一个进程来创建另外一个进程。这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使用pstree命令来查看。在最上面是init程序的执行进程。它是所有进程的老祖宗。Linux提供了两个函数来创建进程。
1.fork()
fork()提供了创建进程的基本操作,可以说它是Linux系统多任务的基础。该函数在unistd.h库中声明。
printf ( "我是子进程哟,我的PID是:%d\n" ,getpid() ); |
printf ( "我是父进程,我的PID是:%d,我的子进程PID是:%d\n" ,getpid(),pid ); |
在调用fork()之前,只有一个进程,但是fork()之后,将产生一个该进程的子进程,该子进程完全复制父进程,此时父子两个进程同时运行。在fork()的时候,如果返回的是0,则说明该进程是子进程。如果返回大于0则说明是父进程。如果小于0(其实是-1),则说明创建进程失败了。
每个进程都有一个唯一标示符,即PID,可以使用getpid()来获取。父进程返回的pid其实是子进程的pid。
貌似这样看,fork()之后也没有什么作用。其实不然,如果fork()之后跟其他linux功能使用,还是用处很大的。比如我们可以在父子进程中通过通信协议来通信,就可以协同完成一些任务了。
2.exec系列函数
如果只有fork(),肯定是不完美的,因为fork()只能参数一个父进程的副本。而exec系列函数则可以帮助我们建立一个全新的新进程。
int execl( const char *path, const char *arg, ...); |
int execlp( const char *file, const char *arg, ...); |
int execle( const char *path, const char *arg , ..., char * const envp[]); |
int execv( const char *path, char * const argv[]); |
int execvp( const char *file, char * const argv[]); |
以上函数在unistd.h声明。
下面我们以execl()函数为例:
execl( "/bin/ls" , "ls" , "-l" ,NULL); |
printf ( "如果execl执行失败,这个就会打印出来了\n" ); |
该程序运行到execle()时,载入ls程序,并且覆盖当前程序的空间。这样就参数了一个新的进程,但是注意,这个新进程的PID跟载入它的进程是一样的。
3.fork()和exec()一起调用
fork()可以创建子进程,但是子进程只是父进程的副本。我们可以利用exec()函数在子进程来重新载入一个全新的进程。下面看一个两个函数联用的列子。
execl( "/bin/ls" , "ls" , "-l" ,NULL); |
首先,fork建立子进程,然后在子进程中使用execl()产生一个ls程序的进程。而父进程则调用wait()来等待,直到子进程调用结束。
我们都知道,进程就是正在执行的程序。而在Linux中,可以使用一个进程来创建另外一个进程。这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使用pstree命令来查看。在最上面是init程序的执行进程。它是所有进程的老祖宗。Linux提供了两个函数来创建进程。
1.fork()
fork()提供了创建进程的基本操作,可以说它是Linux系统多任务的基础。该函数在unistd.h库中声明。
printf ( "我是子进程哟,我的PID是:%d\n" ,getpid() ); |
printf ( "我是父进程,我的PID是:%d,我的子进程PID是:%d\n" ,getpid(),pid ); |
在调用fork()之前,只有一个进程,但是fork()之后,将产生一个该进程的子进程,该子进程完全复制父进程,此时父子两个进程同时运行。在fork()的时候,如果返回的是0,则说明该进程是子进程。如果返回大于0则说明是父进程。如果小于0(其实是-1),则说明创建进程失败了。
每个进程都有一个唯一标示符,即PID,可以使用getpid()来获取。父进程返回的pid其实是子进程的pid。
貌似这样看,fork()之后也没有什么作用。其实不然,如果fork()之后跟其他linux功能使用,还是用处很大的。比如我们可以在父子进程中通过通信协议来通信,就可以协同完成一些任务了。
2.exec系列函数
如果只有fork(),肯定是不完美的,因为fork()只能参数一个父进程的副本。而exec系列函数则可以帮助我们建立一个全新的新进程。
int execl( const char *path, const char *arg, ...); |
int execlp( const char *file, const char *arg, ...); |
int execle( const char *path, const char *arg , ..., char * const envp[]); |
int execv( const char *path, char * const argv[]); |
int execvp( const char *file, char * const argv[]); |
以上函数在unistd.h声明。
下面我们以execl()函数为例:
execl( "/bin/ls" , "ls" , "-l" ,NULL); |
printf ( "如果execl执行失败,这个就会打印出来了\n" ); |
该程序运行到execle()时,载入ls程序,并且覆盖当前程序的空间。这样就参数了一个新的进程,但是注意,这个新进程的PID跟载入它的进程是一样的。
3.fork()和exec()一起调用
fork()可以创建子进程,但是子进程只是父进程的副本。我们可以利用exec()函数在子进程来重新载入一个全新的进程。下面看一个两个函数联用的列子。
execl( "/bin/ls" , "ls" , "-l" ,NULL); |
首先,fork建立子进程,然后在子进程中使用execl()产生一个ls程序的进程。而父进程则调用wait()来等待,直到子进程调用结束。
- linux创建进程fork的方法步骤
fork创建进程 函数原型如下 #include// 必须引入头文件,使用fork函数的时候,必须包含这个头文件,否则,系统找不到fork函数 pid_t fork(void); //void代表没有 ...
- linux创建进程和等待进程退出
在WIN32下,在一个进程里我们可以使用CreateProcess()创建一个进程,然后通过调用WaitForSingleObect(), WaitForMultipleObject()等待进程退出. ...
- 创建守护进程步骤与setsid() -- linux deamon进程
原创:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且 ...
- Linux下进程的创建
这篇文章主要是讲解到Linux进程的控制,包括程序和进程.守护进程.守护进程的出错处理. 1.程序和进程 程序(program)是存放在磁盘文件中的可执行文件,程序的执行实例被称为进程(process ...
- LINUX编程学习笔记(十四) 创建进程与 父子进程内存空间
1什么是进程:进程是一个执行中的程序 执行的程序: 代码->资源->CPU 进程有很多数据维护:进程状态/进程属性 所有进程属性采用的一个树形结构体维护 ps -a//所有进程 ps - ...
- Linux学习--进程创建
进程创建 在Linux系统下,自己可以创建进程: 当进程执行时,它会被装载进虚拟内存,为程序变量分配空间,并把相关信息添到 task_struct里. 进程内存布局分为四个不同的段: • 文本段,包含 ...
- Linux下进程的创建过程分析(_do_fork do_fork详解)--Linux进程的管理与调度(八)
Unix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(确切说vfork创造出来的是轻量 ...
- linux 创建守护进程的相关知识
linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...
- linux 新进程的创建
慕课18原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.背景知识: 1. ...
随机推荐
- Python之文件操作:os模块
Python os 模块提供了一个统一的操作系统接口函数 一.对于系统的操作 1.os.name 当前使用平台 其中 ‘nt’ 是 windows,’posix’ 是linux 或者 unix 2.o ...
- [应用篇]第四篇 JSTL之C标签介绍
JSTL 核心标签库标签共有13个,功能上分为4类: 1.表达式控制标签:out.set.remove.catch 2.流程控制标签:if.choose.when.otherwise 3.循环标签:f ...
- Error : getaddrinfo ENOTFOUND registry.npmjs.org registry.npmjs.org:443
环境 阿里云 centos7 node v8.11.3 npm 5.6.0 错误 npm update 解决 ping registry.npmjs.org 发现https://registry.np ...
- "Access restriction: The type BASE64Encoder is not accessible due to restrict"问题解决
问题如题: Eclipse中有一种叫做存取限制的机制,来防止你错误使用那些非共享的API.通常来说,Eclipse做的是对的,因为两点,我们不想要使用非共享API的,而且Eclipse知道什么是共享的 ...
- zoj 2314 Reactor Cooling (无源汇上下界可行流)
Reactor Coolinghttp://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 Time Limit: 5 Seconds ...
- Goolge-Guava Concurrent中的Service
最近在学习了下Google的Guava包,发现这真是一个好东西啊..由于平时也会写一些基于多线程的东西,所以特意了解了下这个Service框架.这里Guava包里的Service接口用于封装一个服务对 ...
- ArrayList既然继承自AbstractList抽象类,而AbstractList已经实现了List接口,那么ArrayList类为何还要再实现List接口呢?
https://www.cnblogs.com/bluejavababy/p/4320545.html
- 【BZOJ】4033: [HAOI2015]树上染色 树上背包
[题目]#2124. 「HAOI2015」树上染色 [题意]给定n个点的带边权树,要求将k个点染成黑色,使得 [ 黑点的两两距离和+白点的两两距离和 ] 最大.n<=2000. [算法]树上背包 ...
- JSP和Servlet面试题
1.讲下servlet的执行流程. Servlet的执行流程也就是servlet的生命周期,当服务器启动的时候生命周期开始,然后通过init()<启动顺序根据web.xml里的startup-o ...
- 【leetcode 简单】第二十题 合并两个有序数组
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n. ...