嵌入式学习-IO进程-Day04

嵌入式学习-IO进程-Day04

进程的函数接口

fork和Vfork

回收进程资源

wait

waitpid

退出进程

获取进程号(getpid,getppid)

守护进程

守护进程的特点

创建步骤

exec函数族

线程

概念

线程和进程的区别

线程资源

线程函数接口

创建线程(pthread_create)

退出线程

进程的函数接口

fork和Vfork

1.fork(): 子进程拷贝父进程的数据段,代码段

vfork(): 子进程与父进程共享数据段

2.fork(): 父子进程执行次序不确定

vfork(): 保证子进程先运行,在调用exec()或exit()之前,与父进程数据共享,在exec()或exit()调用之后,父进程才能运行

总结:fork: 更通用,适用于需要创建一个完全独立的子进程的场景,vfork: 更适用于子进程立即执行 exec() 覆盖其自身的场景,因为它避免了不必要的地址空间复制,提高了性能。

回收进程资源

wait

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

pid_t wait(int *wstatus);
功能:回收子进程资源(阻塞)
参数:status:子进程退出状态,不接受子进程状态设为NULL
返回值:成功:回收的子进程的进程号
        失败:-1
用法:wait(NULL);

示例代码:

waitpid

pid_t waitpid(pid_t pid, int *status, int options);
功能:回收子进程资源
参数:
    pid:>0     指定子进程进程号
         =-1   任意子进程
         =0    等待其组ID等于调用进程的组ID的任一子进程
         <-1   等待其组ID等于pid的绝对值的任一子进程
    status:子进程退出状态
    options:0:阻塞
    WNOHANG:非阻塞
返回值:正常:结束的子进程的进程号
      当使用选项WNOHANG且没有子进程结束时:0
      出错:-1
      
wait(NULL== waitpid(-1,NULL,0) //阻塞回收任意子进程资源
waitpid(pid,NULL,0); //阻塞回收指定进程
waitpid(-1,NULL,WNOHANG);不阻塞回收任意子进程

非阻塞示例代码

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>

int main(int argc, char const *argv[])
{
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("fork err");
        return -1;
    }
    else if (pid == 0)
    {
        printf("in child\n");
        sleep(5); // 睡眠是为了看到现象
        printf("子进程退出\n");
    }
    else
    {
        printf("尝试回收我的子进程资源\n");
        while (1)
        {
            pid_t result = waitpid(pid, NULL, WNOHANG);
            if (result == 0)
            {
                printf("子进程还在运行.....\n");
                sleep(1);
            }
            else
            {
                printf("子进程结束\n");
                break;
            }
        }
    }
    return 0;
}

退出进程

void exit(int status);
功能:结束进程,刷新缓存
参数:退出的状态
不返回。
void _exit(int status);
功能:结束进程,不刷新缓存
参数:status是一个整型的参数,可以利用这个参数传递进程结束时的状态。
    通常0表示正常结束;
    其他的数值表示出现了错误,进程非正常结束
    
    
    
exit和return的区别
exit:函数,结束进程。
return:关键字,结束函数。

exit和_exit的区别
exit():刷新缓存区,关闭所有打开的文件指针
_exit():立即终止进程,不会执行上述操作

示例代码:

获取进程号(getpid,getppid

pid_t getpid(void);
功能:获取当前进程的进程号
pid_t getppid(void);
功能:获取当前进程的父进程号

练习:创建子进程,在父子进程中分别获取他们的进程号和父进程号,获取结束,回收子进程资源,退出进程。

守护进程

守护进程的特点

守护进程是后台进程;生命周期比较长,从系统启动时开启,系统关闭时结束;它是脱离控制终端且周期执行的进程。

创建步骤

1.创建子进程,父进程退出

子进程成为孤儿进程,成为后台进程(fork)

2.在子进程当中创建会话

让子进程成为会话组组长,为了让子进程完全脱离终端;setsid()

3.改变进程的运行路径为根目录

原因进程运行的路径不能被删除或卸载;chdir("/")

4.重设文件权限掩码

增大进程创建文件时权限,提高灵活性;umask(0)

5.关闭文件描述符

将不需要的文件关闭;close();

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char const *argv[])
{
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("fork err");
        return -1;
    }
    else if (pid == 0)
    {
        //在子进程中创建新的会话
        setsid();
        //改变路径到根目录
        chdir("/");
        //改变文件权限掩码
        umask(0);
        //关闭文件描述符
        for (int i = 0; i < 3; i++)
        {
            close(i);
        }
       while(1);
    }
    else
    {
       exit(0);
    }
    return 0;
}

练习:

创建一个守护进程,循环间隔1s向文件中写入一串字符“hello”

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("fork err");
        return -1;
    }
    else if (pid == 0)
    {
        // 在子进程中创建新的会话
        setsid();
        // 改变路径到根目录
        chdir("/");
        // 改变文件权限掩码
        umask(0);
        // 关闭文件描述符
        for (int i = 0; i < 3; i++)
        {
            close(i);
        }
        // 打开一个文件
        int fd = open("/tmp/info.log", O_WRONLY | O_CREAT | O_TRUNC, 0777);
        if (fd < 0)
        {
            perror("open err\n");
            return -1;
        }
        // 循环写入
        while (1)
        {
            write(fd, "hello\n", 6);
            sleep(1);
        }
    }
    else
    {
        exit(0);
    }
    return 0;
}

exec函数族

作用:在当前进程中执行一个新的程序。

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 execvpe(const char *file, char *const argv[],
                       char *const envp[]);

线程

概念

线程是一个轻量级的进程,为了提高系统的性能引入线程,线程和进程都参与统一的调度。

线程和进程的区别

共同点:都为操作系统提供了并发能力

不同点:

  1. 调度和资源上:线程是系统调度的最小单位,进程是资源分配的最小单位。
  2. 地址空间上:同一个进程创建多个线程共享进程资源,进程的地址空间相互独立。
  3. 通信方面:线程的通信相对简单,只需要通过全局变量就能实现。但是需要考虑临界资源(临界资源包括同一个文件,全局变量等)访问的问题,进程间的通信相对复杂,需要借助进程间的通信机制(借助3g-4g的的内核空间)
  4. 安全性方面:线程的安全性相对较差,当进程结束时会导致所有线程退出,进程相对于安全。

线程资源

共享的资源:可执行的指令,静态的数据,进程中打开的文件描述符,信号处理函数。当前的工作目录,用户的ID,用户的组ID

私有资源:线程ID (TID)、PC(程序计数器)和相关寄存器、堆栈、错误号 (errno)、信号掩码和优先级、执行状态和属性

线程标识:

主线程的 TID 和 PID 是相同的,每个子线程有自己独立的 TID,但它们都共享相同的 PID

线程函数接口

创建线程(pthread_create)

头文件
#include <pthread.h>
int pthread_create(pthread_t  *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
功能:创建一个线程
参数:1.pthread_t *thread:线程标识,成功创建线程后,pthread_create 会将新线程的 ID 写入 thread 指向的内存位置。
      2.const pthread_attr_t *attr:线程属性, NULL:代表设置默认属性
      3. void *(*start_routine):函数名,代表线程函数,指向一个函数的指针,这个函数就是线程的执行体(也就是线程的入口函数)。该函数必须符合 void *(*start_routine)(void *) 的原型,即接受一个 void * 类型的参数,并返回一个 void * 类型的值。
      
  函数指针一般都是作为函数的参数使用:意思是在一个函数中回调另一方功能函数

      4.void *arg:传递给 start_routine 的参数。arg 是一个通用的指针,可以传递任何类型的数据(通常是一个结构体的指针,以便传递多个参数)。如果不需要传递参数,可以传递 NULL
返回值:成功返回0
        失败返回错误码

示例代码

退出线程

void pthread_exit(void *retval);功能:用于执行退出线程
参数:任意类型的数据,一般写NULL
返回值:无
用法:
pthread_exit(NULL);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ASO优化手机游戏的秘密功能

在本文中&#xff0c;我们将尝试弄清楚手机游戏的 ASO 优化是否有任何特定功能。移动游戏在移动应用世界中占有特殊的地位&#xff0c;因为它们是最赚钱的细分市场。然而&#xff0c;今天&#xff0c;我们将关注的不是货币化&#xff0c;而是基础知识—文本和视觉优化、它们在游…

AI自动生成PPT哪个软件好?智能生成PPT不再熬夜做课件

大概这世上&#xff0c;都是职场牛马对“PPT”这三个字母的头痛反应最大吧&#xff01; 是的&#xff0c;就连各个年级段的老师也是很头痛——愁着怎样能在排版整齐的情况下&#xff0c;将必考知识点都呈现在PPT每一张幻灯片页面里...... 近期打听到用人工智能生成ppt课件&am…

2024全国大数据与计算智能挑战赛火热报名中!

一年一度的 全国大数据与计算智能挑战赛震撼来袭&#xff01; 报名速通&#xff1a; https://www.datafountain.cn/special/BDSSF2024 大数据与决策&#xff08;国家级&#xff09;实验室连续三年组织发起全国大数据与计算智能挑战赛&#xff0c;旨在深入挖掘大数据应用实践中亟…

基于模型预测控制(MPC)储能控制策略-多目标哈里斯鹰(MOHHO)算法的储能容量配置方法

目录 一、主要内容&#xff1a; 二、运行效果&#xff1a; 三、模型预测控制介绍&#xff1a; 四、多目标哈里斯鹰算法&#xff1a; 五、代码数据下载&#xff1a; 一、主要内容&#xff1a; 本研究旨在提出一种双层控制模型&#xff0c;结合模型预测控制&#xff08;MPC…

2024年四非边缘鼠鼠计算机保研回忆(记录版 碎碎念)

Hi&#xff0c;大家好&#xff0c;我是半亩花海。写下这篇博客时已然是金秋十月&#xff0c;心中的石头终于落地&#xff0c;恍惚间百感交集。对于保研这条路&#xff0c;我处于摸着石头过河、冲击、随缘的这些状态。计算机保研向来比其他专业难&#xff0c;今年形势更是艰难。…

开发一个微信小程序要多少钱?

在当今数字化时代&#xff0c;微信小程序成为众多企业和个人拓展业务、提供服务的热门选择。那么&#xff0c;开发一个微信小程序究竟需要多少钱呢&#xff1f; 开发成本主要取决于多个因素。首先是功能需求的复杂程度。如果只是一个简单的信息展示小程序&#xff0c;功能仅限…

Pytest中fixture的scope详解

pytest作为Python技术栈下最主流的测试框架&#xff0c;功能极为强大和灵活。其中Fixture夹具是它的核心。而且pytest中对Fixture的作用范围也做了不同区分&#xff0c;能为我们利用fixture带来很好地灵活性。 下面我们就来了解下这里不同scope的作用 fixture的scope定义 首…

一图解千言,了解常见的流程图类型及其作用

在企业管理、软件研发过程中&#xff0c;经常会需要进行各种业务流程梳理&#xff0c;而流程图就是梳理业务时必要的手段&#xff0c;同时也是梳理的产出。但在不同的情况下适用的流程图又不尽相同。 本文我们就一起来总结一下8 种最常见的流程图类型 数据流程图 数据流程图&…

WordPress任推帮网盘拉新数据统计插件

任推邦是国内一线的APP推广项目分发和流量变现平台&#xff0c;隶属聚名科技集团&#xff08;国家级高新技术企业、AAA重合同守信用企业&#xff0c;安徽百强企业&#xff09;,任推邦目前是阿里、字节、百度、迅雷、美团等品牌一级用户增长服务商&#xff0c;已入驻各类自媒体达…

基于Java的茶叶商城设计与实现(源码+定制+开发)茶叶电商系统开发、茶叶电商平台开发、茶叶在线销售平台设计与开发

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

利士策分享,新知速学,稳赚之道

利士策分享&#xff0c;新知速学&#xff0c;稳赚之道 在当今这个日新月异的时代&#xff0c;新知识、新技术如雨后春笋般层出不穷。 对于渴望在商海中稳操胜券的投资者而言&#xff0c;快速掌握新领域知识&#xff0c;并以此为基石赚取稳定收益&#xff0c;无疑是一项至关重…

从Apple Intelligence到远程机器人手术:更快、更安全的网络成企业业务关键

过去&#xff0c;企业的业务模式和网络架构相对简单&#xff0c;数据传输量不大&#xff0c;远程访问需求也不多。企业对网络的要求主要集中在确保基本的连通性和可用性。如今&#xff0c;企业通过将产品与各项高新技术深度融合&#xff0c;赋予传统产品活力和竞争力。以苹果公…

【AAOS】Android Automotive 14模拟器源码下载及编译

源码下载 repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r20 repo sync -c --no-tags --no-clone-bundle 源码编译 source build/envsetup.sh lunch sdk_car_x86_64-trunk_staging-eng make -j8 运行效果 emualtor Home All apps …

[LeetCode] 415.字符串相加

给定两个字符串形式的非负整数 num1 和num2 &#xff0c;计算它们的和并同样以字符串形式返回。 你不能使用任何內建的用于处理大整数的库&#xff08;比如 BigInteger&#xff09;&#xff0c; 也不能直接将输入的字符串转换为整数形式。 示例 1&#xff1a; 输入&#xff…

Python编程探索:从基础语法到循环结构实践(下)

文章目录 前言&#x1f377;四、 字符串拼接&#xff1a;连接多个字符串&#x1f378;4.1 使用 操作符进行字符串拼接&#x1f378;4.2 使用 join() 方法进行字符串拼接&#x1f378;4.3 使用 format() 方法进行格式化拼接&#x1f378;4.4 使用 f-string&#xff08;格式化字…

DS几大常见排序讲解和实现(中)(14)

文章目录 前言一、希尔排序( 缩小增量排序 )基本思想实现思路时间空间复杂度分析总结 二、选择排序基本思想实现思路时间空间复杂度分析总结 三、堆排序四、冒泡排序基本思想实现思路总结 五、归并排序基本思想实现思路总结 六、计数排序基本思想总结 总结 前言 承上启下&#…

CPP-TCP80优化

CPP-TCP80优化 调整场景&#xff1a;(无法弹出认证界面或弹出慢&#xff09; 其中判断是否需要调整的方法如下&#xff1a;高峰期每隔20s show一次如下命令&#xff0c;查看Drop列数值是否有增加。 说明&#xff1a; web认证情况下&#xff0c;如果同时进行web重定向用户较多&…

【服务器部署】Docker部署小程序

一、下载Docker 安装之前&#xff0c;一定查看是否安装docker&#xff0c;如果有&#xff0c;卸载老版本 我是虚拟机装的Centos7&#xff0c;linux 3.10 内核&#xff0c;docker官方说至少3.8以上&#xff0c;建议3.10以上&#xff08;ubuntu下要linux内核3.8以上&#xff0c…

TPAMI 2024 | TokenCut:使用自监督 Transformer 和正则化剪切对图像和视频中的对象进行分割

TokenCut&#xff1a;使用自监督 Transformer 和正则化剪切对图像和视频中的目标进行分割 作者&#xff1a;Yangtao Wang, Xi Shen, Yuan Yuan, Yuming Du, Maomao Li, Shell Xu Hu, James L. Crowley, Dominique Vaufreydaz 摘要 在本文中&#xff0c;我们描述了一种基于图…

使用Windbg分析dump文件排查C++软件异常的一般步骤与要点分享

目录 1、概述 2、打开dump文件,查看发生异常的异常类型码 3、查看发生异常的那条汇编指令 3.1、汇编代码能最直接、最本真的反映出崩溃的原因 3.2、汇编指令中访问64KB小地址内存区,可能是访问了空指针 3.3、汇编指令中访问了很大的内核态的内存地址 3.4、汇编指令中访…