C/C++进程线程超详细详解

目录

前言

一、进程基础

1.进程概念

2.进程特征

3.进程状态(如图清晰可见)

4,进程的标识

实例代码如下:

5.进程的种类

实例shell脚本程序如下:

二、进程API

1.创建子进程

实例代码如下:

2.exec函数族

 函数族讲解图如下所示:

实例代码如下所示: 

3.结束进程

实例代码如下所示:

4.给进程收尸(释放进程占用的资源)

 wait实例代码如下:

waitpid实例代码如下: 

总结


前言

进程和线程的广泛意义是什么?

进程是计算机中运行的程序的实例。它具有独立的内存空间和资源,是操作系统分配和管理资源的基本单位。每个进程都拥有独立的地址空间、全局变量和文件打开等资源,进程之间相互独立。进程之间通常通过进程间通信(IPC)机制进行数据交互。

线程是进程中的一个执行单元。一个进程可以包含多个线程,这些线程共享进程的地址空间和资源,可以同时执行不同的代码路径。线程之间可以通过共享内存进行数据交换,因为它们可以访问相同的全局变量和堆内存。


一、进程基础

1.进程概念

进程是一个独立的可调度的任务
    (1)进程是一个抽象实体。当系统在执行某个程序时,分配和释放的各种资源
    (2)进程是一个程序的一次执行的过程
进程和程序的区别
    程序是静态的,它是一些保存在磁盘上的指令的有序集合,没有任何执行的概念
    进程是一个动态的概念,它是程序执行的过程,包括创建、调度和消亡
    进程是程序执行和资源管理的最小单位

2.进程特征

动态性 ----程序一次运行过程
并发性 ----可以同时运行多个进程
独立性 ----每个进程在各自独立的虚拟内存中运行
异步性 ----多个运行的进程之间相互没有关系

3.进程状态(如图清晰可见)

4,进程的标识

(1)主要的进程标识
    进程号(Process Identity Number,PID)
    父进程号(Parent Process ID,PPID)
    
(2)PID唯一地标识一个进程。可以通过以下两个函数获得:
    pid_t getpid(void)     //获取进程ID
    pit_t getppid(void)    //获取父进程ID

实例代码如下:

int main(void){printf("pid = %d\n",getpid());printf("ppid = %d\n",getppid());return 0;}

 在终端运行的结果以及ps命令作用结果如下:

5.进程的种类

(1)交互进程:
    该类进程是由shell控制和运行的。交互进程既可以在前台运行,也可以在后台运行。
    
(2)批处理进程:
    该类进程不属于某个终端,它被提交到一个队列中以便顺序执行。

实例shell脚本程序如下:

        终端输入命令如下:

        touch test.sh
        chmod a+x test.sh  
        test.sh内容如下:
        ls
        touch 1.txt 2.txt 3.txt
        ls /
        cat fork1.c

 运行shell脚本文件如下:

     peter@ubuntu:~/2308/proc/day01_code$ ./test.sh
     1.txt  3.txt   exit.c   fork2.c   main.c    myproc.c  test.sh  wait.c   waitpid.c
     2.txt  exec.c  fork1.c  getpid.c  Makefile  test.c    wait     waitpid
     bin   cdrom  etc   initrd.img      lib    lost+found  mnt  proc  run   snap  swapfile  tftpboot         u  sr  vmlinuz
     boot  dev    home  initrd.img.old  lib64  media       opt  root  sbin  srv   sys       tmp                 var    vmlinuz.old
     #include <stdio.h>
     #include <sys/types.h>
     #include <unistd.h>

     int main(void)
     {
         fork();
         printf("hello world\n");
         return 0;
      }

 (3)守护进程:
          该类进程在后台运行。它一般在Linux启动时开始执行,系统关闭时才结束

二、进程API

1.创建子进程

pid_t fork(void);

fork调用过程:
    1,映射新的进程虚拟空间,该进程称为子进程。
    2,将父进程的各个数据段中的数据拷贝到子进程中
    3,父子进程共享代码段
    4,fork()调用过程返回两个值:
                  第一个值:给父进程返回子进程的ID号
                  第二个值:给子进程返回0
           调用失败返回:-1
    5,父子进程,从fork()调用的下一条语句同时运行   

实例代码如下:

void fun(void){int i;for(i = 0 ; i  < 7; i++){printf("我是子进程,我要好好学习\n");sleep(1);}}int main(void){int i;pid_t pid;if((pid = fork()) < 0){perror("fork");exit(1);}else if(!pid)fun();elsefor(i = 0 ; i  < 7; i++){printf("我是父进程,我要努力赚钱\n");sleep(1);}return 0;}

2.exec函数族

//加载另一个程序在进程的空间中执行
#include <unistd.h>
extern char **environ;

int execl(const char *path, const char *arg, ... /* (char  *) NULL */);
int execlp(const char *file, const char *arg,.../* (char  *) NULL */);
int execle(const char *path, const char *arg,../*, (char *) NULL,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 envp[]);

 函数族讲解图如下所示:

 

实例代码如下所示: 

int main(void)
{int i;pid_t pid;if((pid = fork()) < 0){perror("fork");exit(1);}else if(!pid){   //子进程:执行另一个程序,如:ls
#if 0//execl("/bin/ls","ls","-l",NULL);//execlp("ls","ls","-l",NULL);char * arg[] = {"ls","-l",NULL};//execv("/bin/ls",arg);execvp("ls",arg);
#else//execl("/home/peter/2308/proc/day01_code/myproc","./myproc",NULL);char * env[] = {"name = peter","passwd = 123",NULL};//execle("/home/peter/2308/proc/day01_code/myproc","./myproc",NULL,env);char * arg[] = {"./myproc",NULL};execve("/home/peter/2308/proc/day01_code/myproc",arg,env);
#endif}else{   //父进程循环打印for(i = 0 ; ; i++){printf("我是父进程,我要努力赚钱\n");sleep(1);}}return 0;
}

3.结束进程

实例代码如下所示:

#include <stdlib.h>
void exit(int status);   //在结束进程之前,会先刷新缓冲,释放缓冲区,关闭打开的文件,然后再结束进程。#include <unistd.h>void _exit(int status);   //直接结束进程,不会刷新缓冲,释放缓冲区,关闭打开的文件//参数 ---status:  0-表示正常结束,非0-表示异常结束例如: int main(void){printf("hello world");//exit(1);     _exit(1);while(1);  return 0;     //在main函数中,执行return语句,return会调用exit()}

4.给进程收尸(释放进程占用的资源)

(1)wait
    #include <sys/types.h>
    #include <sys/wait.h>
    //作用:给任意一个子进程收尸
     如果子进程没有结束,则父进程会阻塞,直到子进程结束为止。
     如果父进程没有子进程,则wait函数立即返回。               
    pid_t wait(int *wstatus);   
    //参数  ----- 保存子进程结束状态的变量地址
    //返回值 ----成功:收尸的子进程的ID,失败:-1
    

 wait实例代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(void)
{int i;pid_t pid1,pid2;int status;if((pid1 = fork()) < 0){perror("fork");exit(1);}else if(!pid1){for(i = 0 ; i  < 7; i++){printf("子进程1--pid = %d\n",getpid());sleep(1);}exit(0);}if((pid2 = fork()) < 0){perror("fork");exit(1);}else if(!pid2){for(i = 0 ; i  < 3; i++){printf("子进程2--pid = %d\n",getpid());sleep(1);}exit(120);}if(wait(&status) < 0){perror("wait");exit(1);}printf("给子进程收完尸\n");printf("status = %d\n",WEXITSTATUS(status));return 0;
}

 (2)waitpid
    //作用:给指定的进程收尸
    pid_t waitpid(pid_t pid, int *wstatus, int options);
    //参数1  ---pid:
                pid > 0   给进程号为pid的子进程收尸
                pid = -1  与wait()相同,给任意子进程收尸
                pid = 0   给与当前进程在同一个进程组的中任意子进程收尸
                pid < -1  给进程组ID为|pid|的进程组中任意子进程收尸
    //参数2 ----保存子进程结束状态的变量地址
    //参数3 ---- 选项,一般为0

waitpid实例代码如下: 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(void)
{int i;pid_t pid1,pid2;int status;if((pid1 = fork()) < 0){perror("fork");exit(1);}else if(!pid1){for(i = 0 ; i  < 7; i++){printf("子进程1--pid = %d\n",getpid());sleep(1);}exit(234);}if((pid2 = fork()) < 0){perror("fork");exit(1);}else if(!pid2){for(i = 0 ; i  < 3; i++){printf("子进程2--pid = %d\n",getpid());sleep(1);}exit(120);}if(waitpid(pid1,&status,0) < 0){perror("wait");exit(1);}printf("给子进程收完尸\n");printf("status = %d\n",WEXITSTATUS(status));return 0;
}


总结

      本篇文章针对进程线程进行超详细讲解,希望能够帮到大家!

       以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!

       希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!

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

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

相关文章

搭建自己的pypi服务器

要搭建自己的 PyPI 服务器&#xff0c;您可以使用 warehouse 项目&#xff0c;它是 PyPI 的开源实现。下面是一些基本步骤&#xff1a; 准备环境&#xff1a; 安装 Python安装 PostgreSQL 数据库 克隆 warehouse 项目&#xff1a; git clone https://github.com/pypa/wareh…

Socket网络编程练习题四:客户端上传文件(多线程版)

题目 想要服务器不停止&#xff0c;能接收很多客户上传的图片&#xff1f; 解决方案 可以使用循环或者多线程 但是循环不合理&#xff0c;最优解法是&#xff08;循环多线程&#xff09;改写 代码实战 客户端代码 package com.heima;import java.io.*; import java.net.S…

在Windows11上安装ubuntu虚拟机

一开始是参考了 VMware17虚拟机安装Ubuntu最新版本(Ubuntu22.04LTS)详细步骤 专栏的1和2来的。但是后面总是提示operating system not found&#xff0c;就参考vmware安装ubuntu时总是提示operating system not found&#xff0c;选择典型安装而不是专栏选择的自定义安装&#…

深度学习算法在工业视觉落地的思考

0.废话 距离上次的栈板识别的思考已经过去3个月&#xff0c;中间根据客户的需求和自己的思考&#xff0c;对软件又重新做了调整。但是整体上还是不满意。 0.1 老生常谈的工业视觉落地架构 对于软件架构&#xff0c;我实在没有太多的参考。没办法&#xff0c;公司根本不关心软…

Redis与Mybatis

作者在学习Redis整合时使用JDBC与Jedis&#xff0c;但是呢&#xff0c;现如今的环境下&#xff0c;Mybatis系列ORM框架是更受关注的方法&#xff0c;作者有一点点Mybatis基础&#xff0c;Mybatisplus几乎忘的差不多了&#xff0c;现对Redis整合Mybatis相关知识进行梳理&#xf…

使用华为eNSP组网试验⑵-通过端口地址进行静态路由

有了网络模拟器可以对很多网络应用场景进行模拟&#xff0c;既方便学习又有利于实际的网络实施。 之前因为没有用过&#xff0c;用过了才知道eNSP的好处。但是与思科模拟器不同&#xff0c;连接是自动连接&#xff0c;不能确定端口&#xff0c;比如使用指定的光纤端口或者RJ45的…

CSS详细基础(六)边框样式

本期是CSS基础的最后一篇~ 目录 一.border属性 二.边框属性复合写法 三.CSS修改表格标签 四.内边距属性 五.外边距属性 六.其他杂例 1.盒子元素水平居中 2.清除网页内外元素边距 3.外边距的合并与塌陷 4.padding不会撑大盒子的情况 七.综合案例——新浪导航栏仿真 …

在 msys2/mingw 下安装及编译 opencv

最简单就是直接安装 pacman -S mingw-w64-x86_64-opencv 以下记录一下编译的过程 1. 安装编译工具及第三方库 pacman -S --needed base-devel mingw-w64-x86_64-toolchain unzip gccpacman -S python mingw-w64-x86_64-python2 mingw-w64-x86_64-gtk3 mingw-w64-x86_64-…

QT按钮介绍

目录 按钮基类 QAbstractButton QPushButton QToolButton QRadioButton QCheckBox 按钮基类 QAbstractButton 这是按钮的基类&#xff0c;它是继承QWidget类 它可对当前的图标&#xff0c;标题等进行设置。 它有自己的一些信号与槽函数&#xff1a; /* 当按钮被激活时(即…

区块链(7):p2p去中心化之初始化websoket服务端

1 整个流程梳理 服务开启onStart()连接打开onOpen()处理接收到的消息onMesage()连接关闭onClose()异常处理onError()2 创建p2p实现类 package com.example.demo.service;import com.example.demo.entity.BlockChain; import org.java_websocket.WebSocket; import org.java_we…

Chrome(谷歌浏览器)如何关闭搜索栏历史记录

目录 问题描述解决方法插件解决&#xff08;亲测有效&#xff09;自带设置解决步骤首先打开 地址 输入&#xff1a;chrome://flags关闭浏览器&#xff0c;重新打开Chrome 发现 已经正常 问题描述 Chrome是大家熟知的浏览器&#xff0c;但是搜索栏的历史记录如何自己一条条的删…

asp.net core mvc 文件上传,下载,预览

//文件上传用到了IformFile接口 1.1文件上传视图 <form action"/stu/upload" method"post" enctype"multipart/form-data"><input type"file" name"img" /><input type"submit" value"上传&…

Flink-CDC——MySQL、SqlSqlServer、Oracle、达梦等数据库开启日志方法

目录 1. 前言 2. 数据源安装与配置 2.1 MySQL 2.1.1 安装 2.1.2 CDC 配置 2.2 Postgresql 2.2.1 安装 2.2.2 CDC 配置 2.3 Oracle 2.3.1 安装 2.3.2 CDC 配置 2.4 SQLServer 2.4.1 安装 2.4.2 CDC 配置 2.5达梦 2.4.1安装 2.4.2CDC配置 3. 验证 3.1 Flink版…

国庆day1

发送数据 #include<myhead.h>//消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }Msg_ds;#define SIZE sizeof(Msg_ds)-sizeof(long) //正文大小 int main(int argc, const char *argv[]) {//1、创建key值key_t ke…

Spring MVC 中的数据验证技术

一、前言 在Web开发中&#xff0c;数据验证是不可或缺的一部分。Spring MVC 框架提供了强大的数据验证支持&#xff0c;可以帮助我们轻松地对用户提交的数据进行验证。 二、实现 Spring MVC 使用 JSR-303 验证规范&#xff08;Hibernate Validator 是其参考实现&#xff09;…

Microsoft Office无法重装报错30015-44(3) 0-2031(17004)

1.问题描述 由于迁移文件夹导致Microsoft office软件无法使用&#xff0c;于是准备卸载重装&#xff0c;但是点击OfficeSetup.exe出现报错30015-44(3) 关闭后出现以下报错0-2031(17004) 2. 尝试的解决方式 重启后仍然无法解决问题 2.1 参考官网解决办法 手动从控制面板&…

利用ICG-NH2/Amine进行DNA标记1686147-55-6星戈瑞

ICG-NH2&#xff08;吲哚菁绿胺&#xff09;可以用于DNA标记&#xff0c;这种标记方法通常涉及到DNA上的胺基反应基团和ICG-NH2之间的化学反应。以下是一种常见的方法&#xff0c;用于利用ICG-NH2标记DNA分子&#xff1a; 步骤&#xff1a; 1.准备目标DNA&#xff1a;你需要准…

Spring源码分析(四) Aop全流程

一、Spring AOP基础概念 1、基础概念 连接点(Join point)&#xff1a;能够被拦截的地方&#xff0c;Spring AOP 是基于动态代理的&#xff0c;所以是方法拦截的&#xff0c;每个成员方法都可以称之为连接点&#xff1b;切点(Poincut)&#xff1a;每个方法都可以称之为连接点&…

Java 23种设计模式分类概括以及应用介绍

创建型模式&#xff1a;5种 单例模式&#xff08;Singleton Pattern&#xff09; 思想&#xff1a;确保一个类只有一个实例&#xff0c;并提供全局访问点&#xff0c;它的主要目的是限制类的实例化并确保所有代码都共享相同的实例。 应用&#xff1a;Runtime类、数据库连接池、…

Sentinel学习——CAP理论,微服务中的雪崩问题,和Hystix的解决方案 Sentinel的相关概念 + 下载运行

前言 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 本篇博客介绍CAP理论&#xff0c;微…