当前位置: 首页 > news >正文

【转载】Linux下进程的建立

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

1.fork()

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

view source print ?
#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系列函数则可以帮助我们建立一个全新的新进程。

view source print ?
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()函数为例:

view source print ?
#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()函数在子进程来重新载入一个全新的进程。下面看一个两个函数联用的列子。

view source print ?
#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()来等待,直到子进程调用结束。

转载于:https://www.cnblogs.com/GT_Andy/archive/2011/06/21/2086129.html

相关文章:

  • SQL SERVER2005几个性能优化综述
  • windows phone7 mango 多人在线游戏
  • ISAG短信上下行的纠结
  • ASP.NET MVC3书店--第三节 视图与视图模型(转)
  • ASP.NET Session丢失问题原因及解决方案
  • SetWaitableTimer 通过异步程序调用(APC)实现的定时功能
  • C#扩展和收缩代码
  • Activity的taskAffinity属性
  • C# Winform利用POST传值方式模拟表单提交数据(Winform与网页交互)
  • Oracle Namespace 说明
  • linux目录配置 FHS
  • 排除软件缺陷的两种重要手段
  • 我收藏了 NHibernate之旅系列文章导航
  • 首篇文章测试。
  • hdu 2159 FATE 解题报告
  • 【笔记】你不知道的JS读书笔记——Promise
  • ES6核心特性
  • GraphQL学习过程应该是这样的
  • js面向对象
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • js中的正则表达式入门
  • Just for fun——迅速写完快速排序
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • maya建模与骨骼动画快速实现人工鱼
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • Vue 动态创建 component
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • Yii源码解读-服务定位器(Service Locator)
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 服务器从安装到部署全过程(二)
  • 服务器之间,相同帐号,实现免密钥登录
  • 搞机器学习要哪些技能
  • 规范化安全开发 KOA 手脚架
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 如何利用MongoDB打造TOP榜小程序
  • 微信支付JSAPI,实测!终极方案
  • 云大使推广中的常见热门问题
  • 责任链模式的两种实现
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • (175)FPGA门控时钟技术
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (70min)字节暑假实习二面(已挂)
  • (二)fiber的基本认识
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (十)T检验-第一部分
  • ..回顾17,展望18
  • ./configure、make、make install 命令
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .Family_物联网
  • .Mobi域名介绍
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换