Linux 操作系统&进程

本文详细介绍了Linux中的进程概念,包括进程的动态性和并发性特点,资源分配,状态管理,进程间的关系,以及关键函数如fork、exec、system和vfork的使用。讲解了如何查看进程,创建、结束和管理进程,以及进程间通信的方式。
摘要由CSDN通过智能技术生成

目录

目录

1.进程概念

1.1 进程的基本概念

1.2  查看进程

1.3 进程的特点

1.4 进程的资源分配

1.5  进程的状态

1.6  进程管理

1.7 进程间关系

1.8 创建进程

2.进程相关函数

2.1 获取进程   pid   --getpid

2.2 结束进程

2.3 fork  -- 创建子进程

2.4 进程等待函数

2.5 Vfork  --  创建子进程函数

3. system函数

4  exec 函数族


1.进程概念

1.1 进程的基本概念

        代码  --  程序员写出来字符文件  --  磁盘中

        程序  --  将字符文件编译得到的二进制文件  --  磁盘中

        进程  --  正在运行的程序/程序被加载到内存中  --  内存中

        同一个程序,多次加载到内存中,产生的是不同的进程。

1.2  查看进程

LInux系统下:ps - ef  ps -aux

1.3 进程的特点

        动态性:进程的实质是程序的一次执行过程,进程是动态产生,动态消亡的。

        并发性:任何进程都可以同其他进程一起并发执行。

        独立性: 进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。

        异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的,不可预知的速度向前推进。

1.4 进程的资源分配

计算机给每一个进程都会分配4G的虚拟内存:

分为4个部分:
        堆区:-- 需要手动开辟,手动释放

        栈区:-- 局部变量

        数据段:-- 全局区、静态区

        代码段:-- 代码  常量区

1.5  进程的状态

        执行态:当下正在占用CPU,cpu划分时间片

        就绪态:已经做好了可以执行的一切准备,等待cpu划分时间片

        等待态:等待某事件发生

1.6  进程管理

暂停  恢复  杀死进程

Linux:
指令:ps  - ef

          ps - aux     获取PID号

ctrl  + c     ctrl + \

kill -9 PID   给PID这个进程发送9信号,9信号专门用来杀死进程

1.7 进程间关系

父子关系

父进程:该进程是由谁引导产生的,谁就是该进程的父进程;

1.8 创建进程

        1:运行一个可执行程序

        2:在程序中使用函数,可以创建进程  fork vfork

        2、进程相关API函数

2.进程相关函数

2.1 获取进程   pid   --getpid

头文件:     

   #include <sys/types.h>

   #include <unistd.h>

函数原型:

pid_t getpid(void);//获取当前进程的进程号


形参: 无
返回值: pid_t 类型的 pid 号

pid_t getppid(void);//获取当前进程的父进程的进程号


形参: 无
返回值: 当前进程的父进程的进程号

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc,char*argv[])
{
    pid_t pid=getpid();
    pid_t ppid=getpid();
    printf("pid=%d,ppid=%d\n",pid,ppid);
    while (1)
    {
        
    }
    return 0;
}

2.2 结束进程

        1.在main函数中运行return,可以结束进程(return的功能是退出当前函数)

        2.exit(0);//结束进程,结束之前可以刷新缓冲区。

  头文件:

#include <stdlib.h>

   函数原型:

void exit(int status);

        形参:status:进程退出时的状态,一般写0;

        返回值:无

        3 _exit(0);//结束进程,结束之前不刷新缓存区

插入:

        sleep函数

  头文件:

#include <unistd.h>


  函数原型:

unsigned int sleep(unsigned int seconds);


 形参: seconds 秒数
 功能: 阻塞性, 在该函数的位置, 延时 seconds 秒之后, 解除阻塞
 sleep(1); : 代码在该位置阻塞 1 秒, 1 秒之后往下继续运行

2.3 fork  -- 创建子进程

头文件:

    #include <sys/types.h>
    #include <unistd.h>

 函数原型:

pid_t fork(void)

        形参:无

        返回值:在父进程中返回子进程的PID号(>0的值)

                    在子进程中,返回0;

                    失败返回-1;

解释:进程中运行到fork的时候,我们就有两个进程,原本的通过./a.out产生的父进程,通过fork产生的是子进程

fork 创建的子进程的特点:

        1.子进程复制父进程的所有资源(堆区,栈区,数据段,代码段),父子进程相互独立,互不干扰;

        2.子进程从fork的下一行开始运行;

        3.父子进程并发运行,谁先谁后看cpu调度

特殊进程介绍:

        父子进程: 父进程拥有子进程的 PID 号;
        0 号进程: 操作系统的引导程序
        1 号进程/祖先进程: 操作系统运行起来的第一个进程
        孤儿进程: 父进程已经结束, 子进程还在运行, 此时就产生孤儿进程, 孤儿进程会被
收养,进程退出之后帮其收尸
        僵尸进程: 子进程退出了, 但是父进程太忙了, 没空帮其回收资源, 僵尸进程时一种几乎放弃了所有资源, 但是占用一个进程号!
s-睡眠 r-运行 z-僵尸


2.4 进程等待函数

1.等待任意子进程退出  -- wait

阻塞性函数:等待任意子进程退出,只有子进程退出了,该函数才能解除阻塞!

头文件:

  #include <sys/types.h>
  #include <sys/wait.h>


 函数原型:

pid_t wait(int *wstatus);

        形参:wstatus -- 保存进程退出时的状态,一般写NULL

        返回值:成功返回为其收尸的子进程的进程号;

2.等待指定子进程退出 

头文件:

#include <sys/types.h>
#include <sys/wait.h>

 函数原型:

pid_t waitpid(pid_t pid,int *wstatus,int options);

        形参:pid  --  你要等待哪一个子进程退出

        可以写-1,表示等待任意子进程退出(类似于wait!)

        wstatus:NULL;

        options :  填0,阻塞等待子进程退出,(类似于wait)

        填WNOHANG,不阻塞如果子进程刚好退出,帮其收尸,没退出,不阻塞,直接就过去了,运行下一行代码;

返回值:

        如果option填0,返回为其收尸的子进程的进程号;

        如果 options 填WNOHANG,如果子进程刚好退出,帮其收尸,返回为其收尸的子进程的进程号,如果子进程没有退出,不阻塞,直接返回0;

        waitpid(-1,NULL,0); == wait(NULL);


2.5 Vfork  --  创建子进程函数

头文件:

  #include <sys/types.h>
  #include <unistd.h>

  函数原型:

pid_t vfork(void);

        形参:无

        返回值:在父进程中返回子进程的PID号

        在子进程中返回0

特点:子进程先运行,运行结束,父进程才能运行

           子进程和父进程共享资源

单独使用vfork函数会出现段错误

解决段错误:

        方式1:子进程中必须有exit(0);

        方式2:结合exec

3. system函数

功能:在当前进程中运行其他进程

头文件:

 #include<stdio.h>

函数原型:

int system(const char *command);

        形参:command:新的进程的启动命令

        如果是自己写的可执行程序,填写绝对路径+可执行程序名

举例:名为:main 在/home/yym/路径中,要写绝对路径:

        system(“/home/yym/main”);

        如果是系统提供的:不同加路径

        举例:system("ls-l -a -i");

4  exec 函数族

        往往和fork/vfork配合使用

        在当前进程中启动另一个进程,当前的进程空间完全被取代,仅仅保留了原本的PID号

头文件:

        #include <unistd.h>
        函数原型:int execl(const char *pathname, const char *arg, .../* (char *) NULL */);

        形参:pathname  --  新的可执行程序的路劲+可执行程序名,必须是绝对路径

        arg:可变传参,可以有1个或者多个

        arg1  --  填可执行程序名

        arg2  --  给可执行程序传递的参数

        最后必须以NULL结束

int execlp(const char *file, const char *arg, .../* (char *) NULL */);
        形参: file 新的可执行程序的程序名,如果是自己的,写绝对路径;
        如果是系统的直接写可执行程序名即可
        arg: 可变传参, 可以有 1 个或者多个
        arg1 -- 填可执行程序名
        arg2 -- 给可执行程序传递的参数
        。 。 。
        最后必须以 NULL 结尾

int execv(const char *pathname, char *const argv[]);
形参: pathname -- 新的可执行程序的路径+可执行程序名
        必须是绝对路径(不管是自己的还是系统的 ls/clear 等等)
        argv: 指针数组, 直接看如下举例
        将 execl("/bin/ls","ls","-l","-a",NULL);改为 execv, 如下:
        char *argv[] = {"ls","-l","-a",NULL};
        execv("/bin/ls",argv)

int execvp(const char *file, char *const argv[]);
形参: file 新的可执行程序的程序名,如果是自己的,写绝对路径;
        如果是系统的直接写可执行程序名即可
        argv: 指针数组, 直接看如下举例
        将 execlp("ls","ls","-l","-a",NULL);改为 execv, 如下:
        char *argv[] = {"ls","-l","-a",NULL};
        execvp("ls",argv);

vfork特点:
        子进程没有自己的空间,和父进程共用空间,子进程先运行,退出之后父进程才能运行

vfork+exec 函数结合的特点:

        子进程将被分配空间, 不再和父进程共享空间, 父子进程并发运行

fork+exec 函数结合的特点:

        父子进程并发运行

        父子进程空间各自独立

插入补充说明:

        _LINE_    就是当前的行号  %d

        _FUNCTION_   就是当前的函数名  %s

        _FILE_  就是当前的文件名  %s

printf("行:%d\n", _LINE_ );

printf("文件名:%s\n",  _FILE_  );

printf("函数名:%s\n",  _FUNCTION_ );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值