网络编程中对进程的理解(Linux + GCC)

原创 2016年05月31日 15:05:39

理解进程(Process)

          接下来了多进程服务器实现的重点内容——进程。其定义如下:

              “占用内存空间的正在运行的程序”。

              假如各位从网上下载了LBreakout游戏并安装到硬盘。此时的游戏并非进程,而是程序。因为游戏并未进入运行状态。下面开始运行程序。此时游戏被加载到主内存并进入运行状态,这时才可称为进程。如果同时运行多个LBreakout程序,则会生成相应数量的进程,也会占用相应进程数的内存空间。

              再举个例子。假设各位需要进行文档相关操作,这是应打开文档编辑软件。如果工作的同时还想听音乐,应打开MP3播放器。另外,为了与朋友聊天,再打开MSN软件。此时共创建3个进程。从操作系统的角度看,进程是程序流的基本单位,若创建多个进程,则操作系统将同时进行。有时一个程序运行过程中也会产生多个进程。接下来要创建的多进程服务器就是其中的代表。编写服务器端前,先了解一下通过程序创建进程的方法。


提示:  CPU核的个数与进程数

             拥有2个运算设备的CPU称作双核(Daul)CPU,拥有4个运算器的CPU称作4核(Quad)CPU。也就是说1个CPU中可能包含多个运算设备(核)。核的个数与可同时运行的进程数相同。相反,若进程数超过核数,进程将分时使用CPU资源。但因为CPU运转速度极快,我们会感到所有进程同时运行。当然,核数越多,这种感觉越明显。


进程ID

         讲解创建进程方法前,先简要说明进程ID。无论进程是如何创建的,所有进程都会从操作系统分配ID。此ID称为“进程ID”,其值为大于2的整数。1要分配给操作系统启动后的(用于协助操作系统)首个进程,因此用户进程无法得到ID值1。接下来观察Linux中正在运行的进程。


运行结果:ps命令语句

ycz@debian8470p:~$ ps au
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      3228  1.7  1.2 199308 105532 tty7    Ss+  11:15   3:28 /usr/bin/X :0 v
root      3270  0.0  0.0  16468   944 tty1     Ss+  11:15   0:00 /sbin/getty 384
root      3271  0.0  0.0  16468   944 tty2     Ss+  11:15   0:00 /sbin/getty 384
root      3272  0.0  0.0  16468   948 tty3     Ss+  11:15   0:00 /sbin/getty 384
root      3273  0.0  0.0  16468   952 tty4     Ss+  11:15   0:00 /sbin/getty 384
root      3274  0.0  0.0  16468   952 tty5     Ss+  11:15   0:00 /sbin/getty 384
root      3275  0.0  0.0  16468   956 tty6     Ss+  11:15   0:00 /sbin/getty 384
ycz       5431  1.0  0.0  21304  3808 pts/0    Ss   14:29   0:00 bash
ycz       5477  0.0  0.0  17048  1284 pts/0    R+   14:29   0:00 ps au
ycz@debian8470p:~$


      可以看出,通过ps指令可以查看当前运行的所有进程。特别需要注意的是,该命令同时列出了PID(进程ID)。另外,上述示例通过指定a和u参数列出了所有进程详细信息。



通过调用fork函数创建进程

     创建进程的方法很多,此处只介绍用于创建多进程服务器端的fork函数。

       #include <unisd.h>

       pid_t fork(void);

                       ----->成功时返回进程ID,失败时返回-1

       fork函数将创建调用的进程副本(概念上略难)。也就是说,并非根据完全不同的程序创建进程,而是复制正在运行的,调用fork函数的进程。另外,两个进程都将执行fork函数调用后的语句(准确地说是在fork函数返回后)。但因为通过同一个进程,复制相同的内存空间,之后的程序流要根据fork函数的返回值加以区分。即利用fork函数的如下特点区分程序执行流程。


      父进程:fork函数返回子进程ID。

      子进程:fork函数返回0


      此处“父进程”(Parent Process)指原进程,即调用fork函数的主体,而“子进程”(Child Process)是通过父进程调用fork函数复制出的进程。接下来讲解调用fork函数后的程序运行流程,如下代码:


//父进程

int gval = 10;
int main(void)
{
     int lval = 20;
     lval+=5;
     gval++;
     pid_t pid = fork();           //复制生成点,pid为子进程ID
     if(pid==0)
         gval++;
     else
         lval++;                   //运行
     ......
}

//子进程
//gval复制为11

int main(void)
{
     //lval复制为25
    ....
    pid_t pid = fork();            //pid为0!
    if(pid==0)
         gval++;                   //运行
    else
         lval++;
    ......
}

           从以上代码中可以看到,父进程调用fork函数的同时复制出子进程,并分别得到fork函数的返回值。但复制前,父进程将全局变量gval增加到11,将局部变量lval的值增加到25,因此在这种状态下完成进程复制。复制完成后根据fork函数的返回类型区分父子进程。父进程将lval的值加1,但这不会影响子进程的lval值。同样,子进程将gval的值加1也不会影响到父进程的gval。因为fork函数调用后分成了完全不同的进程,只是二者共享同一代码而已。接下来给出示例验证之前的内容。


fork.c

#include<stdio.h>
#include<unistd.h>

int gval = 10;
int main(int argc,char *argv[]){
    pid_t pid;
    int lval = 20;
    gval++,lval+=5;

    pid = fork();                     //创建子进程。父进程的pid中存有子进程的ID,子进程的pid是0.
    if(pid==0)                        //if Child Process,子进程执行这2行代码,因为pid为0
    	gval+=2,lval+=2;
    else                              //if Parent Process,父进程执行这2行代码,因为此时pid存有子进程ID
    	gval-=2,lval-=2;

    if(pid==0)
    	printf("Child Proc:[%d,%d] \n",gval,lval);
    else
        printf("Parent Proc:[%d,%d] \n",gval,lval);

    return 0;
}


运行结果:fork.c

ycz@debian8470p:~/program/TCP&&IP/chapter10$ gcc fork.c -o fork
ycz@debian8470p:~/program/TCP&&IP/chapter10$ ./fork
Parent Proc:[9,23]
Child Proc:[13,27]



                从运行结果可以看出,调用fork函数后,父子进程拥有完全独立的内存结构。我认为关于fork函数无需更多示例,希望各位通过该示例充分理解调用fork函数创建进程的方法。




版权声明:本文为博主原创文章,未经博主允许不得转载。

浅谈Linux网络编程的基本内容

今天只是想浅谈一下对于Linux网络编程中一些基本问题的理解。我们知道互联网通信都是基于TCP/IP协议簇的,里面从一开始设计就保证了基本的通信安全和效率问题。 顾名思义的解释:IP(Internet...
  • xianszm007
  • xianszm007
  • 2013年07月28日 21:33
  • 1828

Java网络编程中对Socket的理解

关于网络编程中的Socket和ServerSocket的关系,以及对Scoket中流的操作,一直不太明白,直到看第二遍书和视屏的时候, 豁然开朗,这里作个总结,也是对学习的回顾。 我们在理解TCP通信...
  • xn6517
  • xn6517
  • 2015年08月15日 17:27
  • 577

对于C++网络编程的一点了解

源码包下载;  http://download.dre.vanderbilt.edu/         http://blog.csdn.net/superyao2008/article/deta...
  • xb_0916
  • xb_0916
  • 2015年03月25日 15:53
  • 504

面试题:谈谈对进程的理解?谈谈你对线程的理解?2.进程死锁的原因?如何解决进程死锁?

2.谈谈对进程的理解? 答:首先进程是指在系统中正在运行的一个应用程序;程序一旦运行就是进程,或者更专业化来说:进程是指程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集。从内核的观点...
  • linux12121
  • linux12121
  • 2016年06月29日 22:00
  • 3063

LINUX C网络编程中的心跳机制

在TCP网络通信中,经常会出现客户端和服务器之间的非正常断开,需要实时检测查询链接状态。常用的解决方法就是在程序中加入心跳机制。 从网络上找到,主要有以下方法实现TCP异常断开的检测: S...
  • yuyin86
  • yuyin86
  • 2014年05月04日 18:16
  • 1469

对进程和线程的简单理解

          这几天看了点视频,巩固下基础知识,以前对线程并没有什么概念上的理解,下面我简单总结下:说到线程,不得不提起几个概念:程序、进程、线程程序是计算机指令的集合,它以文件形式存储在磁盘上...
  • chiperfect
  • chiperfect
  • 2010年11月01日 10:29
  • 1406

linux和windows下socket编程的一点区别

本文转自:http://blog.csdn.net/hanshuai8602/article/details/6586396 (以下假设我们的网络通信采用的TCP协议且采用阻塞模式) ...
  • chinawangfei
  • chinawangfei
  • 2015年04月03日 18:16
  • 850

Unix网络编程第三版源码编译

环境: $ cat /etc/issue Ubuntu 12.04.1 LTS \n \l $ cat /proc/version Linux version 3.2.0-48-generic (...
  • HanTangSongMing
  • HanTangSongMing
  • 2014年03月04日 11:56
  • 4709

linux进程及运行状态分析

1、进程与程序的概念: 进程:进程是在操作系统中运行的特定程序,或执行的任务。强调的是程序的运行过程,是动态的。 程序:程序是存储在磁盘上包含可执行机器指令和数据的静态实体。是静态的。 2...
  • zwz19911991
  • zwz19911991
  • 2014年02月08日 10:53
  • 1486

对linux进程的理解

进程是UNIX操作系统抽象概念中最基本的一种,其中涉及进程的定义以及相关的概念,比如线程;它们在内核中如何被列举?如何创建?最终又如何消亡?让我们通过下面的分析,一步步解开内核进程的神秘面纱。 1...
  • LinuxWorking
  • LinuxWorking
  • 2017年10月12日 13:32
  • 83
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:网络编程中对进程的理解(Linux + GCC)
举报原因:
原因补充:

(最多只允许输入30个字)