系统编程(3):进程

news2024/11/24 10:29:54

文章目录

  • 一、概念
    • 1.1 什么是进程?
    • 1.2 进程ID
    • 1.3 进程间通信
    • 1.4 进程的三种态的转换
  • 二、进程控制
    • 2.1 创建进程函数:fork函数
      • 2.1.1 获得pid函数
      • 写代码:
        • 方式一:最简单的
        • 方式二:加入while(1)死循环
        • 方式三:增加自加逻辑,便于看程序运行逻辑
    • 2.2 启动进程函数:exec函数族
      • 2.2.1 exec函数族的使用场景
      • 写代码
    • 2.3 ps和kill命令

一、概念

1.1 什么是进程?

进程指的是正在运行的程序。

下图是进程的三种状态:

在这里插入图片描述

后台进程又叫守护进程。

1.2 进程ID

每个进程都有一个唯一的标识符,即进程ID,简称pid。

1.3 进程间通信

  • 管道通信:有名管道,无名管道
  • 信号通信:信号的发送,信号的接受,信号的处理
  • IPC通信:共享内存,消息队列,信号灯
  • Socket通信

1.4 进程的三种态的转换

  • 就绪态
  • 执行态
  • 阻塞态
    在这里插入图片描述

二、进程控制

2.1 创建进程函数:fork函数

  • fork函数
  • 头文件:include <unistd.h>
  • 函数原型:pid_t fork(void)
  • 返回值:fork函数有三种返回值。
    • 在父进程中,fork返回新创建的子进程的PID
    • 在子进程中,fork返回0
    • 出现出现错误,fork返回一个负值

2.1.1 获得pid函数

  • 获得当前进程的PID:getpid()
  • 获得当前进程的父进程的PID:getppid()

写代码:

方式一:最简单的

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


int main(int argc, char** argv)
{
    pid_t pid;
    pid = fork();

    if(pid < 0)
    {
        printf("fork is error\n");
        return -1;
    }

    // parent process
    if(pid > 0)
    {
        printf("This is parent, parent pid is %d\n", getpid());
    }

    // child process
    if(pid == 0)
    {
        printf("This is child, child pid is %d, parent pid is %d\n", getpid(), getppid());
    }

    return 0;
}
$ gcc main.c -o main.out
$ ./main.out
This is parent, parent pid is 17937
This is child, child pid is 17938, parent pid is 17937

方式二:加入while(1)死循环

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


int main(int argc, char** argv)
{
    pid_t pid;
    pid = fork();

    if(pid < 0)
    {
        printf("fork is error\n");
        return -1;
    }

    // parent process
    if(pid > 0)
    {
        printf("This is parent, parent pid is %d\n", getpid());
        while(1)
        {
            printf("This is parent, parent pid is %d\n", getpid());
        }
    }

    // child process
    if(pid == 0)
    {
        printf("This is child, child pid is %d, parent pid is %d\n", getpid(), getppid());

        while(1)
        {
            printf("This is child, child pid is %d\n", getpid());
        }
    }

    return 0;
}
$ gcc main.c -o main.out
$ ./main.out
This is parent, parent pid is 18134
This is child, child pid is 18135, parent pid is 18134
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
...

方式三:增加自加逻辑,便于看程序运行逻辑

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


int main(int argc, char** argv)
{
    int cnt = 0;
    pid_t pid;
    pid = fork();

    if(pid < 0)
    {
        printf("fork is error\n");
        return -1;
    }

    // parent process
    if(pid > 0)
    {
        printf("This is parent, parent pid is %d\n", getpid());
    }

    // child process
    if(pid == 0)
    {
        printf("This is child, child pid is %d, parent pid is %d\n", getpid(), getppid());
    }

    cnt++;
    printf("cnt: %d, pid: %d\n", cnt, getpid());

    return 0;
}

测试运行:

$ gcc main.c -o main.out
$ ./main.out
This is parent, parent pid is 18180
cnt: 1, pid: 18180
This is child, child pid is 18181, parent pid is 18180
cnt: 1, pid: 18181

这里就是说cnt变量在父进程和子进程里面是独立的拷贝,所以结果不是2而是1.

2.2 启动进程函数:exec函数族

在Linux中并没有exec函数,而是有6个以exec开头的函数族,下面列举了exec函数族的6个函数成员:

  • int execl(const char *path, const char *arg, ...)
  • int execv(const char *path, char *const arg[], ...)
  • int execle(const char *path, const char *arg, ..., char *const envp[])
  • int execve(const char *path,char *const arg[], ..., char *const envp[])
  • int execlp(const char *file, const char *arg, ...)
  • int execvp(const char *file, char *const arg[], ...)

头文件是:unistd.h
最常用的函数是execl函数
exec函数族可以让子进程执行不同的代码

2.2.1 exec函数族的使用场景

在Linux中使用exec函数族主要有以下两种情况:

  1. 当进程认为自己不能再为系统和用户做成任何贡献时,就可以调用任何exec函数族让自己重生。
  2. 如果一个进程想执行另一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生。

写代码

两个代码:
hello.c

#include <stdio.h>


int main(int argc, char** argv)
{
	printf("Hello World!\n");
	return 0;
}

main.c

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


int main(int argc, char** argv)
{
    int cnt = 0;
    pid_t pid;
    pid = fork();

    if(pid < 0)
    {
        printf("fork is error\n");
        return -1;
    }

    // parent process
    if(pid > 0)
    {
        printf("This is parent, parent pid is %d\n", getpid());
    }

    // child process
    if(pid == 0)
    {
        printf("This is child, child pid is %d, parent pid is %d\n", getpid(), getppid());
		// 启动另一个程序hello.out
        execl("/home/liefyuan/Linux/app/08-fork/hello.out", "hello", NULL);
        // execl("/bin/ls","ls", "-al", NULL);
        exit(1);
    }

    cnt++;
    printf("cnt: %d, pid: %d\n", cnt, getpid());

    return 0;
}

测试运行:

liefyuan@ubuntu:~/Linux/app/08-fork$ ./main.out
This is parent, parent pid is 18467
cnt: 1, pid: 18467
This is child, child pid is 18468, parent pid is 18467
Hello World!

只有一次cnt的打印还是父进程打印的,子进程没有cnt打印。
execl函数是“换核不换壳”的,将子进程的内容直接替换成了hello.out程序,而原有的子进程的逻辑就不会再跑了。

2.3 ps和kill命令

ps命令:可以列出系统中当前运行的哪些进程。
举例:

  • ps aux 进程不关联终端
  • ps aps u 都是进程关联终端的
  • ps x 显示所有程序,不以终端来区分
  • ps aux | grep xxx 中间竖线是管道的意思,相当是过滤,除了xxx的都不显示
[root@RK356X:/]# ps a
  PID TTY      STAT   TIME COMMAND
  765 ttyFIQ0  Ss     0:00 -/bin/sh
 3579 ttyFIQ0  R+     0:00 ps a
[root@RK356X:/]# ps au
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       765  0.0  0.1   3168  2068 ttyFIQ0  Ss   11:40   0:00 -/bin/sh
root      3580  0.0  0.0   2992   844 ttyFIQ0  R+   12:57   0:00 ps au

kill命令:用来杀死进程。
举例:kill -9(SIGKILL) PID

可以是使用kill -l来查看所有的相关命令:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/652360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Arduino的LED显示屏驱动实现

基于Arduino的LED显示屏驱动实现可以通过使用Arduino板上的数字引脚和相关库来控制LED显示屏的亮灭和显示效果。LED显示屏加载不出图像怎么办&#xff1f; 下面是基于Arduino的LED显示屏驱动实现的详细介绍&#xff1a; 硬件准备&#xff1a; Arduino开发板&#xff1a;可以使用…

ROS中 mpc_local_planner 局部路径规划器参数配置文件中参数含义

mpc_local_planner与我们比较熟悉的teb_local_planner出自同一研究所&#xff08;多特蒙德大学-控制理论与系统工程研究所&#xff09;&#xff0c;所以参数配置文件中的参数有很多相似之处&#xff0c;很多参数的含义也是相同的&#xff0c;所以熟悉teb_local_planner的参数含…

亚马逊认证考试系列 - 知识点 - 安全组介绍

AWS的安全组是一种虚拟防火墙&#xff0c;可以用于控制进入和离开AWS虚拟私有云(VPC)的流量。安全组是一种网络访问控制列表(NACL)的补充&#xff0c;因为安全组是在实例级别上进行管理的&#xff0c;而NACL是在子网级别上进行管理的。 AWS的安全组可以通过以下方式保护您的资源…

自然语言处理: 第一章N-Gram

一. 理论基础 定义: 语言模型在wiki的定义是统计式的语言模型是一个几率分布&#xff0c;给定一个长度为 m 的字词所组成的字串 W1 , W2 &#xff0c; &#xff0c;Wn &#xff0c;派几率的字符串P(S) P(W1 , W2 , &#xff0c;Wn &#xff0c; )而其中由条件概率公式我们可以…

风景类Midjourney prompt提示词

稳定输出优美风景壁纸的Midjourney prompt提示词。 1\在夏夜&#xff0c;有淡蓝色的星空&#xff0c;海边&#xff0c;流星&#xff0c;烟花&#xff0c;海滩上全是蓝色的玫瑰和绿色的植物&#xff0c;由Ivan Aivazovsky和Dan Mumford&#xff0c;趋势在cgsociety&#xff0c;…

CAN转串口设备在使用时可能遇到的问题和解决方案

上位机软件通过232串口发送数据经过CAN转232设备转换成CAN数据发送到仪表中&#xff0c;仪表接收到指定的数据后&#xff0c;返回特定的CAN数据。 使用过程中可能遇到的问题 1、串口按照规则发送数据后&#xff0c;设备端没有数据返回 遇到这种情况&#xff0c;先检查发送的数…

STM32 Proteu直流电机正反转控制系统限位开关-0035

STM32 Proteu直流电机正反转控制系统限位开关-0035 Proteus仿真小实验&#xff1a; STM32 Proteu直流电机正反转控制系统限位开关-0035 功能&#xff1a; 硬件组成&#xff1a;STM32F103C6单片机 L298N电机控制电路直流电机3个按键&#xff08;正转、反转、停止&#xff09;L…

AM62X+FPGA+AD+vxworks实时操作系统数据采集处理解决方案

Specification Description 处理器 AM6231 at up to 1.2GHz 操作系统 VXWORKS 存储 DDR4,8GB EMMC 接口 •PrPMC接口 •1个USB2.0 •3路RMII •1路RS485 •1路IRIGB •1路RS232 调试接口 JTAG / COP debug port 工业环境监测设备&#xff1a; Specification Desc…

常见优化器详解

优化器 目前有两种主流优化器&#xff1a;随机梯度下降系&#xff08;Stochastic Gradient Descent, SGD&#xff09;和Adam系。 应该认识到的是&#xff0c;优化器并不是某类数学上的优化算法&#xff0c;而是梯度下降&#xff08;一阶迭代法&#xff09;的工程实现方案和包…

VALSE2023-内容总结(正在更新)

博文为精选内容&#xff0c;完整ppt请留言索取 一周内更新完毕&#xff0c;敬请期待 2023年度视觉与学习青年学者研讨会 (Vision And Learning SEminar, VALSE)于6月10日至12日在无锡太湖国际博览中心召开&#xff0c;由中国人工智能学会、中国图象图形学学会主办&#xff0c;…

Transformer与注意力机制

Transformer与注意力机制 1. RNN基础 循环神经网络&#xff08;RNN&#xff09;是专门用来处理自然语言、金融信息等时序数据的一种神经网络。它的结构和运作方式如下图所示&#xff0c;基于马尔可夫决策模型。 图1 循环神经网络的结构和运作方式 应该注意到以下几个性质&a…

周四见 | 物流人的一周资讯

菜鸟618推出“小件3元发全国”服务 6月12日消息&#xff0c;针对美妆商家618期间轻小件的发货需求&#xff0c;菜鸟推出“极致小件3元发全国”服务&#xff0c;利用全国6大基地&#xff0c;100%自营的仓配供应链能力&#xff0c;支持订单高爆发&#xff0c;并提供破损包赔、时…

开源、跨平台安卓摸鱼(投屏)软件 Scrcpy 中文使用指南

废话不说&#xff0c;先上链接&#xff1a;GitHub上的Scrcpy 介绍&#xff1a; Scrcpy 可以将手机画面投射到电脑上&#xff0c;让你可以在电脑上对手机进行操控。Scrcpy 通过 USB 或 Wi-Fi 与安卓手机相连&#xff0c;不需要在手机上安装任何 app&#xff0c;也不需要取得 R…

Vue-插件(plugin)

插件(plugin) 插件是vue中特别强大并且特别简单的一个东西&#xff0c;它可以帮助我们增强vue 插件本质来说就是一个对象&#xff0c;但是这个对象必须包含install(安装)方法&#xff0c;由vue帮助我们调用 只要插件写的足够的好&#xff0c;就可以帮助我们实现很多的功能&a…

一些常用linux命令

系列文章目录 文章目录 系列文章目录一、常用linux命令1. lsof介绍2.查看进程的几种命令3.查看inode号的几种命令4.查看Linux系统负载的命令一般常用的有4种:5.iostat 主要用于输出磁盘IO 和 CPU的统计信息。 总结 一、常用linux命令 1. lsof介绍 lsof可以查看你所打开的文件…

工具篇--5 WIndow/Linux--Mysql binLog日志监听Canal安装

前言&#xff1a;作为一个中间件canal&#xff0c;可以实时的监听到mysql 中表结构及数据的变化&#xff0c; 项目中只需要接入canal &#xff0c;不需要我们在业务中进行aop 或者接口的编写就可以及时的收到数据的变化。 1 介绍&#xff1a; Canal是阿里巴巴开源的一款基于M…

想要用好ChatGPT,首先得学会用提示词!

用好ChatGPT&#xff0c;可以辅助学习~ 期末季&#xff0c;一年中体验过最多地区时差的一段时期&#xff0c;懂的都懂&#x1f632; 放下essay刷个小红薯也都是“赶due病友”…几周内5-6个essay ddl的经历相信不少同学都深有体会。 而今年的一大不同就是有了“哆啦C梦”——…

PostgreSQL行转列

管理拓展 启用拓展 -- 启用拓展 create extension tablefunc; --tablefunc扩展模块包含一系列返回记录表的函数。 create extension "uuid-ossp";--uuid扩展函数拓展启动后&#xff0c;可以在public空间下查看到crosstab函数 卸载函数 drop extension tablefunc…

信创办公–基于WPS的PPT最佳实践系列 (使用母版进行有效设计)

信创办公–基于WPS的PPT最佳实践系列 &#xff08;使用母版进行有效设计&#xff09; 目录 应用背景相关知识操作步骤1、认识母版2、在每页幻灯片底部添加logo图片3、第一张幻灯片和最后一张幻灯片出现logo图片&#xff0c;其他页面不出现4、除了封面封底之外&#xff0c;其他页…

硬件速攻-ATK1218正点原子GPS模块

效果演示(注意室内是没有数据) 模块实物图与接线方法 SPP 可不接(这个连到了模块上的灯) RXD 接单片机TXD TXD 接单片机串口RXD GND 接单片机GND VCC接单片机5V IPEX一定要接送的天线 而且天线要放到室外 再次说明提醒 精简代码与说明 如果你只想获取经纬度而已 你可用屏…