Linux进程和信号

进程和信号

 由于最近比较忙,已经好久没更新了,完成实验任务的同时就更新下吧;

 另外,这时第十一章的内容,直接从shell程序设计跳到了第11章,时间匆忙,暂时这样吧…

进程的结构

 如果有两个用户neil和rick,他们同时运行grep程序在不同的文件中查找不同的字符串。他们使用的进程如图11-1所示。
在这里插入图片描述

 每个进程都会被分配一个唯一的数字编号,称之为进程标识符或PID;当进程被启动时,系统按顺序选择下一个未被使用的数字作为它的PID,当数字已经达到PID可取的最大值,就会回到2开始取未被使用的PID;
 一般的为1的PID是特殊进程init保留的,init进程负责管理其他进程;

 上图11-1中,grep程序代码保存在磁盘文件中;正常情况下,Linux进程不能对用来存放程序代码的内存进行写操作,即程序代码是以只读方式加载到内存中的,它可以被多个进程安全地共享;

查看进程

 ps命令可以显示正在运行的进程、其他用户正在运行的进程或者目前在系统上运行的所有进程;

ps -ef
ps -Af

 这里的-f选项显示进程完整信息,-e等价于-A选项显示所有进程
在这里插入图片描述

在这里插入图片描述

 用BSD风格显示

ps ax

在这里插入图片描述

 下面给出对STAT的描述
在这里插入图片描述

进程调度

 操作系统根据进程的nice值决定优先级,nice值默认为0,值越大,优先级越低; 通过nice设置进程的nice值,renice命令跳转nice值,下面介绍一些命令

ps -l               //可以查看nice值
nice oclock &       //创建一个oclock的进程
renice 10 13652     //跳转PID为13652的基础的nice值为10

 PPID指父进程的PID。

启动新进程

  • 可以在程序内部启动另一个程序,从而创建一个新进程,可以通过库函数system完成,它的声明如下:
#include<stdlib.h>
int system(const char *string);

 system函数作用:运行字符串形式的命令并等待该命令执行完成,执行情况如同hell中执行如下命令:

sh -c string

 编写程序调用ps命令

1.编写如下代码,保存为system1.c

#include<stdlib.h>
#include<stdio.h>

int main(){
    printf("Running ps with system\n");
    system("ps ax");
    printf("Done.\n");
    exit(0);
}

2.编译并运行

 执行如下命令

gcc -o system1 system.c
sudo ./system1

在这里插入图片描述

可以发现执行system1后自动执行sh -c ps ax,然后才执行ps ax
在这里插入图片描述

注意
 一般来说,system函数需要用一个shell来启动需要的程序;由于在执行所需程序前启动一个shell,而且对shell的按照情况及使用的环境的依赖大,因此system函数效率不高。


2021-05-26 更新,暂时就到这了


  • 替换进程映像

 exec系列函数由一组相关的函数组成,他们在进程的启动方式和程序参数的表达方式上各有不同。
 exec函数可以把当前进程替换为一个新进程,新进程由path或file参数指定。可以使用exec函数将程序的执行从一个程序切换到另一个程序,原来的程序就不再运行了。

 下面给出exec系列函数定义原型:

#include<unistd.h>

char **environ;

int execl(const char *path, const char *arg0, ..., (char *)0);
int execlp(const char *file, const char *arg0, ..., (char *)0);
int execle(const char *path, const char *arg0, ..., (char *)0, char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const engv[]);

 事实上,这些函数都是通过execve函数实现的;
 以p结尾的函数通过搜索PATH环境变量查找可执行文件路径;如果可执行文件不在PATH中,需要把包括目录的绝对路径文件名作为参数传递给函数;
 以e结尾的函数,可以通过参数envp传递字符串数组作为新程序的环境变量;

 下面给出一个例子

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

int main(){
  printf("Running ps with execlp\n");
  execlp("ps", "ps", "ax", 0);
  printf("Done.\n");
  return 0;
}

 保存为pexec.c,编译并执行./pexec

复制进程映像

 可以调用fork创建一个新进程,这个系统调用复制当前进程,在进程表中创建一个新的表项,它的许多属性与当前进程是相同的(包括代码),但新进程有自己的数据空间、环境和文件描述符;
 下面给出fork函数定义:

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

pid_t fork(void);

在这里插入图片描述

 父进程调用fork,返回子进程的PID,新进程继续执行,就如原进程一样;但是,子进程调用fork返回0,可以通过它判断是否子进程
 如果fork失败,将返回-1,失败通常由于子进程数太大,超过了上限。
 fork与exec函数结合在一起使用就是创建新进程所需的一切了。

等待一个进程

 有时,父进程可能开启子进程后就结束了,而子进程还在运行,导致结果输出可能比较乱,这时要用到wait函数,下面给出wait函数定义:

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

pid_t wait(int *stat_loc);

 wait系统调用将暂停父进程直到它的子进程结束为止,它返回子进程的PID,通常是已经结束运行的子进程的PID。


2021-05-28 更新


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值