文档章节

linux 多进程编程基础

首席吹牛官
 首席吹牛官
发布于 2015/05/22 12:51
字数 1361
阅读 13
收藏 0

一 linux下进程的理解:
    linux环境下一个进程在内存中有三部分数据:数据段 堆栈段和代码段
    代码段:就是存放程序代码的数据,如果有数个进程运行一个程序,那么他们就可以使用同一个代码段
    堆栈段:存放的是子程序的返回地址 参数以及程序的局部变量
    数据段:存放程序的全局变量 常数以及动态数据分配的数据空间
    系统如果同时运行数个相同的程序,他们之间就不能使用同一个堆栈段和数据段,但是可以使用同一个代码段
二 fork函数的使用
    linux环境下产生新的进程的系统调用是fork函数,一个进程在运行的时候,使用了fork,就会产生另一个进程
例子:
#include <iostream>
using namespace std;
int main(){
    int i;
    if(0==fork()){
        for(i=1;i<1000;i++)
            cout<<"this is child process"<<endl;
    }
    else{
        for(i=1;i<1000;i++)
            cout<<"this is parent process"<<endl;
    }
}
编译运行会在屏幕上交替出现子进程和父进程各打印出的一千条信息,如果程序还在运行使用ps命令可以查看得到两个它在运行
    在linux环境下,一个程序一调用fork函数,系统就会产生信的进程,并且为新的进程准备程序段 堆栈段 数据段等。因为他们的程序是相同的,所以新产生的进程和旧进程使用同一个代码段;对于数据段和堆栈段,系统会复制一份给新进程,父进程的所有数据都可以给子进程,并且他们的运行是分开的,相互之间没有影响,也就是说他们不共享任何数据。如果父进程和子进程需要共享数据,那么需要另一套函数来完成,以后会详细说明的。
    fork完后会产生子进程,对于父进程而言,fork函数返回的是子进程的进程号,对于子进程,fork返回的是零,因此在程序中,我们只要判断fork的返回值,就能判断是在父进程中还是子进程中
    fork函数执行一次,产生一个新进成,复制数据段 堆栈段,但是如果一个大程序在运行的时候,fork的时候复制数据段和堆栈段会不会开销很大呢?linux自有解决的方法:一般CPU都是以页为单位分配空间的,无论是数据段还是堆栈段都是由很多页组成的,当实际执行fork的时候,物理空间上两个进程的数据段和堆栈段还是共享的,逻辑上是分开的,只有当一个进程写某个数据的时候,这时两个进程之间的数据才有了区别,系统会将有区别的页从物理上分开,而其他的不动,从而使系统在空间上的开销达到最小。

三 一个进程启动一个程序的执行
    在linux环境下,一个进程可以启动一个程序的执行可以使用exec类的函数来完成,注意是exec类的函数,这个类中有很多exec函数。
    一个进程一旦调用了exec类的函数,它本身就死了,它的代码段会被替换成新的程序代码,并且废弃原油的数据段和堆栈段,重新分配信的数据段和堆栈段,唯一留下的就是进程号,对于系统而言,还是同一个进程,不过这个进程已经是另一个程序了。如果一个程序想启动另一个程序的执行但是继续运行自己的话,需要结合fork函数和exec函数一块使用
例子:
char command[256];
int main(){
    int rtn;
    while(1){
    cout<<">"<<endl;
    fgets(command,256,cin);
    command[strlen(command)-1]=0;
    if(0==fork()){
        execlp(command,command);
        cerr<<command<<endl;
        exit(cerr);
    }
    else{
        wait(&rtn);
        cout<<"child process return "<<rtn<<endl;
    }
    }
    reutrn 0;
}

    父进程和子进程都使用相同的映像,该函数和普通函数的不同之处是函数如果执行成功会返回来两次,在父进程中返回子进程的pid,子进程中返回0函数返回成功后,父进程和子进程都在fork函数执行后继续执行,如果调用函数不成功则返回值是-1
    wait函数保证父进程运行完后等待子进程退出才退出,否则父进程结束了,子进程还在运行
    好了,linux下的多进程编程就这么点内容,其实让两个进程独立运行很容易,关键的难点是父进程和子进程共享数据进行通信。
例子:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#define FAC_N 65535
void big_loop(int n);
void input_information();
int main(){
        pid_t pid;
        pid=fork();
        switch(pid){
        case -1:
                perror("fork\n");
                break;
        case 0:
                big_loop(FAC_N);
                printf("PID:%d\n",getpid());
                break;
        default:
                input_information();
                printf("PID:%d\n",getpid());
                break;
        }
        wait();
        exit(0);
    }

        void big_loop(int n){
                int i;
                for(i=0;i<n;i++){
                        switch(i%4){
                                case 0:
                                        putchar("-");
                                        break;
                                case 1:
                                        putchar('/');
                                        break;
                                case 2:
                                        putchar('|');
                                        break;
                                case 3:
                                        putchar('\\');
                                        break;
                        }
                putchar('\b');
                }
        } 


        void input_information(){
                int n_table[4],i;
                for(i=0;i<4;i++){
                        printf("Number %d:",i);
                        scanf("%d",&n_table[i]);
                }
        printf("Number1\tNumber2\tNumber3\tNumber4\n");
        printf("%d\t%d\t%d\t%d\n", n_table[0], n_table[1], n_table[2], n_table[3]);
        }

 

转自:http://jiaojiaoni.com/

本文转载自:http://blog.csdn.net/zhx6044/article/details/7770800

上一篇: 哈夫曼树
下一篇: 这就是生活
首席吹牛官
粉丝 9
博文 368
码字总数 191938
作品 0
闵行
程序员
私信 提问
嵌入式Linux学习基础规划篇

嵌入式的学习是需要日积月累的,是通过一点一滴的积累才能成为大神。下面来介绍一下嵌入式linux学习基础规划,目标是达到适应嵌入式应用软件开发、嵌入式系统开发或嵌入式驱动开发的基本素质...

创客学院
2018/04/10
0
0
0-Linux 网络编程修炼指南——内功心法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q1007729991/article/details/69091877 学习交流群: Linux 学习交流群 610441700 说明:本系列文章并不能取代...

--Allen--
2017/04/04
0
0
swoole| swoole wiki 笔记

date: 2019-05-02 20:33:01 title: swoole| swoole wiki 笔记 初心 PHP想做微服务, 离不开 swoole. 而 swoole 进入协程时代后, 是时候抛开历史的包袱, 轻装上阵了. 希望这样过一份 swoole 知...

daydaygo
05/09
0
0
中国最大的互联网综合服务提供商之一.招聘1.后台开发高级工程师.2.客户端开发工程师.

一.后台开发高级工程师.岗位职责:负责severh后台开发 1 责任感强,有较强的逻辑思维能力、沟通能力,能够承担工作压力 2 两年以上linux后台开发经历,linux系统熟悉者优先,熟悉网络开发 3 ...

千觅千寻
2011/07/05
743
3
Python 进程、进程通信 进程池

一:多进程的优点、应用场景 耗CPU计算时多进程速度大于多线程,可以最大化利用CPU计算。多进程有更强的容错性,一个进程出错不会影响其他进程。通常不需要考虑锁和同步资源的问题。 二:进程...

rieuse
2018/09/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

skywalking(容器部署)

skywalking(容器部署) 标签(空格分隔): APM [toc] 1. Elasticsearch SkywalkingElasticsearch 5.X(部分功能报错、拓扑图不显示) Skywalking需要Elasticsearch 6.X docker network create......

JUKE
7分钟前
1
0
解决Unable to find a single main class from the following candidates [xxx,xxx]

一、问题描述 1.1 开发环境配置 pom.xml <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!--一定要对上springboot版本号,因......

TeddyIH
7分钟前
0
0
Dubbo服务限制大数据传输抛Data length too large: 13055248, max payload: 8388608解决方案

当dubbo服务提供者向消费层传输大数据容量数据时,会受到Dubbo的限制,报类似如下异常: 2019-08-23 11:04:31.711 [ DubboServerHandler-XX.XX.XX.XXX:20880-thread-87] - [ ERROR ] [com.al...

huangkejie
10分钟前
0
0
HashMap和ConcurrentHashMap的区别

为了线程安全,ConcurrentHashMap 引入了一个 “分段锁” 的概念。具体可以理解把一个大的 map 拆分成 N 个小的 Map 。最后再根据 key.hashcode( )来决定放到哪一个 hashmap 中去。 hashmap ...

Garphy
11分钟前
0
0
购买SSL证书需要注意哪些问题

为了保障网站的基本安全,为网站部署SSL证书,已经是一种常态了。各大浏览器对于安装了SSL证书的网站会更友好,并且不会发出“不安全”的提示。部署SSL证书之前首先得去给网站购买一个SSL证书...

安信证书
41分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部