转:http://www.cnblogs.com/GT_Andy/archive/2011/06/21/2086129.html

 我们都知道,进程就是正在执行的程序。而在Linux中,可以使用一个进程来创建另外一个进程。这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使用pstree命令来查看。在最上面是init程序的执行进程。它是所有进程的老祖宗。Linux提供了两个函数来创建进程。

1.fork()

  fork()提供了创建进程的基本操作,可以说它是Linux系统多任务的基础。该函数在unistd.h库中声明。  

 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
  
int main()
{
    printf( "创建进程前\n" );
    pid_t pid = fork();
  
    if( !pid ){
        printf( "我是子进程哟,我的PID是:%d\n" ,getpid() );
    }else if( pid>0 ){
        printf( "我是父进程,我的PID是:%d,我的子进程PID是:%d\n",getpid(),pid );
    }else{
        printf( "创建进程失败了哟\n" );
        exit(1);
    }
  
    return 1;
}

  在调用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()函数为例:

 
#include <stdio.h>
#include <unistd.h>
  
int main()
{
    execl("/bin/ls","ls","-l",NULL);
  
    printf("如果execl执行失败,这个就会打印出来了\n");
    return 1;
}

该程序运行到execle()时,载入ls程序,并且覆盖当前程序的空间。这样就参数了一个新的进程,但是注意,这个新进程的PID跟载入它的进程是一样的。

3.fork()和exec()一起调用

  fork()可以创建子进程,但是子进程只是父进程的副本。我们可以利用exec()函数在子进程来重新载入一个全新的进程。下面看一个两个函数联用的列子。

 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
  
int main()
{
    pid_t pid = fork();
    switch( pid )
    {
    case 0:
        printf("子进程\n");
        execl("/bin/ls","ls","-l",NULL);
    case -1:
        printf("fork失败了\n");
        exit(1);
    default:
        wait(NULL);
        printf("完成了哟!\n");
        exit(0);
    }
}

首先,fork建立子进程,然后在子进程中使用execl()产生一个ls程序的进程。而父进程则调用wait()来等待,直到子进程调用结束。

 我们都知道,进程就是正在执行的程序。而在Linux中,可以使用一个进程来创建另外一个进程。这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使用pstree命令来查看。在最上面是init程序的执行进程。它是所有进程的老祖宗。Linux提供了两个函数来创建进程。

1.fork()

  fork()提供了创建进程的基本操作,可以说它是Linux系统多任务的基础。该函数在unistd.h库中声明。  

 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
  
int main()
{
    printf( "创建进程前\n" );
    pid_t pid = fork();
  
    if( !pid ){
        printf( "我是子进程哟,我的PID是:%d\n" ,getpid() );
    }else if( pid>0 ){
        printf( "我是父进程,我的PID是:%d,我的子进程PID是:%d\n",getpid(),pid );
    }else{
        printf( "创建进程失败了哟\n" );
        exit(1);
    }
  
    return 1;
}

  在调用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()函数为例:

 
#include <stdio.h>
#include <unistd.h>
  
int main()
{
    execl("/bin/ls","ls","-l",NULL);
  
    printf("如果execl执行失败,这个就会打印出来了\n");
    return 1;
}

该程序运行到execle()时,载入ls程序,并且覆盖当前程序的空间。这样就参数了一个新的进程,但是注意,这个新进程的PID跟载入它的进程是一样的。

3.fork()和exec()一起调用

  fork()可以创建子进程,但是子进程只是父进程的副本。我们可以利用exec()函数在子进程来重新载入一个全新的进程。下面看一个两个函数联用的列子。

 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
  
int main()
{
    pid_t pid = fork();
    switch( pid )
    {
    case 0:
        printf("子进程\n");
        execl("/bin/ls","ls","-l",NULL);
    case -1:
        printf("fork失败了\n");
        exit(1);
    default:
        wait(NULL);
        printf("完成了哟!\n");
        exit(0);
    }
}

首先,fork建立子进程,然后在子进程中使用execl()产生一个ls程序的进程。而父进程则调用wait()来等待,直到子进程调用结束。

转:Linux创建进程的更多相关文章

  1. linux创建进程fork的方法步骤

    fork创建进程 函数原型如下 #include// 必须引入头文件,使用fork函数的时候,必须包含这个头文件,否则,系统找不到fork函数 pid_t fork(void); //void代表没有 ...

  2. linux创建进程和等待进程退出

    在WIN32下,在一个进程里我们可以使用CreateProcess()创建一个进程,然后通过调用WaitForSingleObect(), WaitForMultipleObject()等待进程退出. ...

  3. 创建守护进程步骤与setsid() -- linux deamon进程

    原创:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且 ...

  4. Linux下进程的创建

    这篇文章主要是讲解到Linux进程的控制,包括程序和进程.守护进程.守护进程的出错处理. 1.程序和进程 程序(program)是存放在磁盘文件中的可执行文件,程序的执行实例被称为进程(process ...

  5. LINUX编程学习笔记(十四) 创建进程与 父子进程内存空间

    1什么是进程:进程是一个执行中的程序 执行的程序: 代码->资源->CPU 进程有很多数据维护:进程状态/进程属性 所有进程属性采用的一个树形结构体维护 ps  -a//所有进程 ps - ...

  6. Linux学习--进程创建

    进程创建 在Linux系统下,自己可以创建进程: 当进程执行时,它会被装载进虚拟内存,为程序变量分配空间,并把相关信息添到 task_struct里. 进程内存布局分为四个不同的段: • 文本段,包含 ...

  7. Linux下进程的创建过程分析(_do_fork do_fork详解)--Linux进程的管理与调度(八)

    Unix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(确切说vfork创造出来的是轻量 ...

  8. linux 创建守护进程的相关知识

    linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...

  9. linux 新进程的创建

    慕课18原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.背景知识: 1. ...

随机推荐

  1. mysql主从同步碰到的问题

    一.mysql 安装https://www.cnblogs.com/jxrichar/p/9248480.html二.主从配置参考https://www.cnblogs.com/superfat/p/ ...

  2. AlloyTouch 简介

    AlloyTouch 是来自于腾讯AlloyTeam团队开发的一个适用用移动端的js组件库. 特性: 1.丰富的组件 选择组件.级联选择组件.轮播组件.全屏滚动组件.下拉刷新组件.上拉刷新任君选择 2 ...

  3. 强大的jQuery网格插件 ParamQuery

    ParamQuery是一种轻量级的jQuery网格插件,基于用于用户界面控制.具有一致API的优秀设计模式jQueryUI Widget factory创建,能够在网页上展示各种类似于Excel和Go ...

  4. 20155117王震宇 实验一《Java开发环境的熟悉》实验报告

    (一)使用JDK编译.运行简单的java程序 命令创建实验目录 输入mkdir 2051117 创建以自己学号命名的文件夹,通过cd命令移动到指定文件夹,输入mkdir exp1创建实验文件夹. 打开 ...

  5. 在Unity中实现屏幕空间反射Screen Space Reflection(2)

    traceRay函数 在上一篇中,我们有如下签名的traceRay函数 bool traceRay(float3 start, float3 direction, out float2 hitPixe ...

  6. 【leetcode 简单】第五题 最长公共前缀

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...

  7. 在mac上安装ruby

    1.先装RVM,一个多版本ruby环境的管理和切换工具 curl -sSL https://get.rvm.io | bash -s stable 会自动装上最新版.更新RVM版本:$ rvm get ...

  8. Test plan

    Options for Test Strategy: 1. Regular test: all the planned test cases will be executed 2. Extented ...

  9. 64_t2

    texlive-biblatex-chem-doc-svn42065-33.fc26.2.no..> 24-May-2017 15:44 1044190 texlive-biblatex-che ...

  10. 2017 CERC

    2017 CERC Problem A:Assignment Algorithm 题目描述:按照规则安排在飞机上的座位. solution 模拟. 时间复杂度:\(O(nm)\) Problem B: ...