Linux系统编程 day9 SIGCHLD and 线程
SIGCHLD信号
只要子进程信号发生改变,就会产生SIGCHLD信号。
借助SIGCHLD信号回收子进程
回收子进程只跟父进程有关。如果不使用循环回收多个子进程,会产生多个僵尸进程,原因是因为这个信号不会循环等待。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/wait.h>
#include<signal.h>void catch_child(int signo) //有子进程终止,发送sigchld信号时,该函数会被内核回调
{pid_t wpid;int status;//while((wpid = wait(NULL))!= -1);while((wpid = waitpid(-1 , &status , 0))!= 0 ){if(WISEXITED(status))printf("catch child:%d , status: %d\n" ,wpid , WEXITSTATUS(status));}
}int main(int argc , char *argv[])
{pid_t pid;int i ;//阻塞sigset_t set ; // 防止在父进程创建sa_mask之前子进程先死亡。sigemptyset(&set);sigaddset(&set , SIGCHLD);sigprocmask(SIG_BLOCK , &set , NULL);for(i = 0 ; i < 5 ; i++){if((pid = fork()) == 0)break;}if(i == 5){struct sigaction act;act.sa_handler = catch_child;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGCHLD , &act , NULL);//解除阻塞sigprocmask(SIG_UNBLOCK , &set , NULL);printf("I am parent , %d\n" , getpid());}else{printf("I am child , %d\n" , getpid());}return 0 ;
}
中断系统调用(非重点)
系统调用分为两类:慢速系统调用和其他系统调用。
慢速系统调用:可能会使进程永远阻塞的一类。eg. read write wait and so on .
其他系统调用:getpid()....
sa_flags 用来设置被信号中断后系统调用是否重启。
进程组和会话
进程组也称之为作业。
创建会话
会话是多个进程组的集合。
注意事项
创建会话不能是进程组组长,该进程变成新会话首进程。
创建新会话丢弃原有的控制终端,该会话没有控制终端。
建立新会话时,先调用fork,父进程终止,子进程调用setsid()。
getsid函数
获取进程所属的会话id
pid_t getsid(pid_t pid);
成功 返回会话id
失败 -1
ps ajx命令查看系统中的进程
组长进程不能成为新会话首进程,新会话首进程必定会成为组长进程。
setsid函数
创建会话,以自己的ID设置进程组ID,同时也是新会话的ID
pid_t setsid(void)
成功:返回调用进程的会话id;
失败:-1
调用setsid函数的进程,既是新的会长,也是新的组长。
守护进程(daemon精灵,进程)
守护进程时Linux中的后台服务进程,通常运行与操作系统后台,脱离控制终端,一般不与用户直接交互 , 周期性的等待某个事件发生或周期性执行某一动作,不受用户登入注销影响。一般使用d结尾的名字。
守护进程创建步骤:
1、fork子进程,让父进程终止。
2、子进程调用setsid创建新会话。
3、通常根据需要,改变工作目录位置,chdir() , 防止目录被卸载
4、通常根据需要,重设置umask文件权限掩码,影响新文件的创建权限
5、通常根据需要,关闭/重定向 文件描述符
6、守护进程 业务逻辑 while()
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc , char *argv[])
{pid_t pid ;int fd ;pid = fork();if(pid > 0){exit(0); //正常终止父进程}else{pid = setsid(); //创建新会话if(pid == -1){perror("set error");exit(1);}int ret = chdir("/home/qqq"); //改变工作目录位置if(ret == -1){perror("chdir error");exit(1);}umask(0022); // 设置掩码权限close(STDIN_FILENO); // 关闭文件描述符fd = open ("/dev/null" , O_RDWR);if(fd == -1){perror("open error");exit(1);}dup2(fd , STDOUT_FILENO); //重定向dup2(fd , STDERR_FILENO);while(1); // 模拟守护进程做的事情}return 0 ;
}
这里由于我不明白为什么需要将标准输入关闭,并且将标准输出和标准错误重定向,我上网查了一些资料:
1、为什么要关闭STDIN_FILENO?
守护进程是在后台运行的,不应该与终端交互,因此不需要标准输入,为防止错误,直接关闭。
2、为什么要将STDOUT and STDERR --->fd 0 ("/dev/null")
"/dev/null"是一个特殊设备,写的什么东西进去都会被吃掉,读取的时候什么也看不到,守护进程不应该输出信息到终端,因此重定向给 fd(此时是 /dev/null)本质上就是为了干净、不占资源、避免潜在错误。
线程(不要将线程和信号混合用)
线程 : LWP,light weight process 轻量级的进程 , 本质仍是进程(Linux环境下)
进程: 独立的进程地址空间 , 有PCB
线程:有独立的PCB,但没有独立的地址空间(共享)
Linux下 线程是最小的执行单位 , 进程是最小分配资源单位,可以看成只有一个线程的进程。
ps -Lf 进程id --->线程号 LWP --->CPU执行的最小单位。
线程可以看作寄存器和栈的集合。
线程共享资源
文件描述符表 、 每种信号的处理方式 、 当前工作目录 、 用户ID和组ID 、 内存地址空间、全局变量
线程非共享资源
线程id 、 处理器现场和栈指针(内核栈) 、独立的栈空间(用户栈) 、 error变量 、 信号屏蔽字
线程的优缺点
优点:提高程序的并发性 , 开销小 , 数据通信、共享数据方便
缺点:库函数不稳定 , 调试、编写困难、GDB不支持 , 对信号支持不友好
优点突出,缺点不明显,能使用线程使用线程
线程控制原语
pthread_self函数
获取线程ID ,注意这里的线程ID和线程号LWP不一样。
线程id是在进程地址空间内部,用来表示线程身份id号
pthread_t pthread_self(void);
成功返回 线程id
pthread_create函数
int pthread_create(pthread_t * tid ,const pthread_attr_t *attr , void *(*start_rountn)(void*) , void *arg);pthread_t * tid:传出参数,传出创建子线程的id。
const pthread_attr_t *attr:线程属性 , 传NULL表示使用默认属性。
void *(*start_rountn)(void*):子线程回调函数,创建成功,pthread_create()函数返回时,该回调函数 会被自动调用。
void *arg:回调函数的参数,没有的话使用NULL返回值 成功 0
失败errno
循环创建5个子线程。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>void* func(void * arg)
{int i = (int) arg;printf("I am %dth child , pid:%d , tid:%lu\n" , i+1 , getpid() , pthread_self());return NULL;
}int main(int argc , char* argv[])
{pthread_t tid;int i ,ret;for(i = 0 ; i < 5 ; i++){ret = pthread_create(&tid , NULL , func , (void*)i);if(ret == -1){perror("pthread_create error");exit(1);} }sleep(i);printf("I am main , pid:%d , tid:%lu\n" , getpid() , pthread_self());return 0 ;
}
pthread_exit函数
将当前线程退出。
void pthread_exit(void *retval);
retval:退出值。无退出值时,NULLexit() ; 退出当前进程
return ; 返回到调用者那里去
pthread_exit() ; 将调用该函数的线程退出
pthread_join函数
阻塞等待线程退出,获取线程退出状态。回收子线程。
int pthread_join(pthread_t thread, void **retval);
返回值 成功 0
失败 -1
pthread_cancel函数
杀死(取消)线程。相当于kill函数。但是需要取消点(保存点) 。如果子线程没有到达取消点,那么该函数无效,我们可以在程序中手动添加一个取消点,使用pthread_testcancel()。成功被cancel函数杀死的进程,可以使用pthread_join回收。
int pthread_cancel(pthread_t thread);
返回值: 成功 0
失败 errno
相关文章:
Linux系统编程 day9 SIGCHLD and 线程
SIGCHLD信号 只要子进程信号发生改变,就会产生SIGCHLD信号。 借助SIGCHLD信号回收子进程 回收子进程只跟父进程有关。如果不使用循环回收多个子进程,会产生多个僵尸进程,原因是因为这个信号不会循环等待。 #include<stdio.h> #incl…...
前后端分离项目在未部署条件下如何跨设备通信
其实我此前也不知道这个问题怎么解决,也没有想过—因为做的项目大部分都是前后端分离的,前端直接用后端的部署好的环境就行了。最近也是有点心高气傲开始独立开发,一个人又写前端又写后端也是蛮累的,即使有强有力的cursor也很累很…...
基于Python的多光谱遥感数据处理与分类技术实践—以农作物分类与NDVI评估为例
多光谱遥感数据包含可见光至红外波段的光谱信息,Python凭借其丰富的科学计算库(如rasterio、scikit-learn、GDAL),已成为处理此类数据的核心工具。本文以Landsat-8数据为例,演示辐射校正→特征提取→监督分类→精度评…...
vscode python 代码无法函数跳转的问题
TL; DR; python.languageServer 配置成了 None 导致 vscode python 代码无法函数跳转 详细信息 mac 环境下 vscode 正常 command 鼠标左键 可以跳转到定义或者使用位置,但是我的为何不知道失效了 我一开始以为是热键冲突,结果发现 mac 好像没办法定…...
SAS宏核心知识与实战应用
1. SAS宏基础 1.1 核心概念 1.1.1 宏处理器 宏处理器在SAS程序运行前执行,用于生成动态代码,可实现代码的灵活定制。 通过宏处理器,可基于输入参数动态生成不同的SAS代码,提高代码复用性。 1.1.2 宏变量 宏变量是存储文本值的容器,用&符号引用,如&var,用于存储…...
Unity 脚本使用(二)——UnityEngine.AI——NavMesh
描述 Singleton class 用于访问被烘培好的 NavMesh. 使用NavMesh类可以执行空间查询(spatial queries),例如路径查找和可步行性测试。此类还允许您设置特定区域类型的寻路成本,并调整寻路和避免的全局行为。 静态属性࿰…...
从项目真实场景中理解二分算法的细节(附图解和模板)
遇到一个真实场景里使用二分算法的问题,本以为可以放心交给小师弟去做,结果出现了各种问题,在此梳理下二分算法的核心思想和使用细节。 文章目录 1.场景描述2.场景分析3.二分算法的精髓3.1 核心模板3.2 二分过程图解3.3 各种区间写法3.3.1 闭…...
金融图QCPFinancial
QCPFinancial 是 QCustomPlot 中用于绘制金融图表(如蜡烛图/K线图)的核心类。以下是其关键特性的详细说明: 一、主要属性 属性类型说明dataQSharedPointer<QCPFinancialDataContainer>存储金融数据的数据容器chartStyleQCPFinancial:…...
Jetson Orin NX 16G 配置GO1强化学习运行环境
这一次收到了Jrtson Orin NX, 可以进行部署了。上一次在nano上的失败经验 Jetson nano配置Docker和torch运行环境_jetson docker-CSDN博客 本次的目的是配置cuda-torch-python38环境离机运行策略。 Jetson Orin NX SUPER 1. 烧录镜像 参考链接在ubuntu系统中安装sdk manag…...
文档管理 Document Management
以下是关于项目管理中 文档管理 的深度解析,结合高项(如软考高级信息系统项目管理师)教材内容,系统阐述文档管理的理论框架、核心流程及实战应用: 一、文档管理的基本概念 1. 定义 文档管理是对项目全生命周期中产生的各类文档进行规范化管理的过程,包括创建、存储、版…...
【Pandas】pandas DataFrame truediv
Pandas2.2 DataFrame Binary operator functions 方法描述DataFrame.add(other)用于执行 DataFrame 与另一个对象(如 DataFrame、Series 或标量)的逐元素加法操作DataFrame.add(other[, axis, level, fill_value])用于执行 DataFrame 与另一个对象&…...
Linux 内核中 cgroup 子系统 cpuset 是什么?
cpuset 是 Linux 内核中 cgroup(控制组) 的一个子系统,用于将一组进程(或任务)绑定到特定的 CPU 核心和 内存节点(NUMA 节点)上运行。它通过限制进程的 CPU 和内存资源的使用范围,优…...
Windows 同步-互锁变量访问
互锁变量访问 应用程序必须同步对多个线程共享的变量的访问。 应用程序还必须确保对这些变量的作以原子方式执行(完全或根本不执行)。 对正确对齐的 32 位变量的简单读取和写入是原子作。 换句话说,你最终不会只更新变量的一部分;所有位都以…...
深度学习3.5 图像分类数据集
%matplotlib inline import torch import torchvision from torch.utils import data from torchvision import transforms from d2l import torch as d2l代码执行流程图 #mermaid-svg-WWhBmQvijswiICpI {font-family:"trebuchet ms",verdana,arial,sans-serif;font-…...
js原型链prototype解释
function Person(){} var personnew Person() console.log(啊啊,Person instanceof Function);//true console.log(,Person.__proto__Function.prototype);//true console.log(,Person.prototype.__proto__ Object.prototype);//true console.log(,Function.prototype.__prot…...
从M个元素中查找最小的N个元素时,使用大顶堆的效率比使用小顶堆更高,为什么?
我们有一个长度为 M 的数组,现在我们想从中找出 最小的 N 个元素。例如: int a[10] {12, 3, 5, 7, 19, 0, 8, 2, 4, 10};从中找出 最小的 4 个元素。 正确方法:使用大小为 N 的「大顶堆」 原因分析: 我们想保留最小的 4 个元素…...
【知识】性能优化和内存优化的主要方向
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 前言 现在有很多论文,乍一看很高级,实际上一搜全是现有技术的堆砌,但是这种裁缝式的论文依然能发表在很好的会议和期…...
VS Code + GitHub:高效开发工作流指南
目录 一、安装 & 基本配置 1.下载 VS Code 2.安装推荐插件(打开侧边栏 Extensions) 3.设置中文界面(可选) 二、使用 VS Code 操作 Git/GitHub 1.基本 Git 操作(不输命令行!) 2.连接 GitHub(第一次使用) 三、克隆远程仓库到 VS Code 方法一(推荐): 方…...
软件测试之接口测试常见面试
一、什么是(软件)接口测试? 接口测试:是测试系统组件间接口的一种测试方法 接口测试的重点:检查数据的交换,数据传递的正确性,以及接口间的逻辑依赖关系 接口测试的意义:在较早期开展,在软件开发的同时…...
发送百度地图的定位
在vuephp写的聊天软件项目中,增加一个发送百度地图的定位功能 在 Vue PHP 的聊天软件中增加发送百度地图定位功能,需要从前端定位获取、地图API集成、后端存储到消息展示全流程实现。以下是详细步骤: 一、前端实现(Vue/Uni-app…...
11、Refs:直接操控元素——React 19 DOM操作秘籍
一、元素操控的魔法本质 "Refs是巫师与麻瓜世界的连接通道,让开发者能像操控魔杖般精准控制DOM元素!"魔杖工坊的奥利凡德先生轻抚着魔杖,React/Vue的refs能量在杖尖跃动。 ——以神秘事务司的量子纠缠理论为基,揭示DOM…...
uniapp-商城-33-shop 布局搜索页面以及u-search
shop页面上有一个搜索,可以进行商品搜索,这里我们先做一个页面布局,后面再来进行数据i联动。 1、shop页面的搜索 2、搜索的页面代码 <navigator class"searchView" url"/pagesub/pageshop/search/search"> …...
npm的基本使用安装所有包,安装删除指定版本的包,配置命名别名
npm的基本使用安装所有包,安装删除指定版本的包,配置命名别名 安装所有依赖指定版本安装/删除包给 npm 脚本配置“命令别名(自定义命令)” ✅ 一、安装所有包(恢复依赖) 如果项目中已经存在 package.json…...
【dataframe显示不全问题】打开一个行列超多的excel转成df之后行列显示不全
出现问题如下图: 解决方案~ display.width解决列显示不全 pd.set_option(display.max_columns,1000) pd.set_option(display.width, 1000) pd.set_option(display.max_colwidth,1000) pd.set_option(display.max_rows,1000)...
Windows下Golang与Nuxt项目宝塔部署指南
在Windows下将Golang后端和Nuxt前端项目打包,并使用宝塔面板部署的步骤如下 一、Golang后端打包 交叉编译为Linux可执行文件 在Windows PowerShell中执行: powershell复制下载 $env:GOOS "linux" $env:GOARCH "amd64" go build…...
真实趋势策略思路
该交易策略通过一系列技术指标的计算与逻辑判断,旨在捕捉市场趋势的反转与延续点,以实现盈利。其主要交易逻辑思路可以概括如下: 1. 趋势与动量分析 策略首先利用动量函数计算收盘价的短期(3周期)变化,通过…...
江奇霖惊喜亮相泡泡岛音乐节,新歌首唱+合作舞台燃动现场
2025年4月20日,江奇霖受邀参加2025泡泡岛音乐与艺术节东南站。现场献唱三首歌曲,超5万名观众现场一同感受音乐的魅力。 在泡泡岛SPECIAL SET特别企划舞台中,江奇霖带来新歌的首唱,温暖的旋律如低语倾诉,观众们也纷纷喊…...
【HarmonyOS】ArKUI框架
目录 概述 声明式开发范式 基于ArKUI的项目 • 1.创建资源文件 • 2.引用资源 • 3.引用系统资源: • 系统资源有哪些 • 4. 在配置和资源中引用资源 声明式语法 UI描述规范 UI组件概述 组件化 组件渲染控制语法 修改…...
使用 Nacos 的注意事项与最佳实践
📹 背景 Nacos 凭借其强大💪的服务发现、配置管理和服务管理能力,成为构建分布式系统的得力助手。然而,要充分发挥 Nacos 的优势,实现系统的高性能、高可用,掌握其使用过程中的注意事项和最佳实践至关…...
Megatron - LM 重要文件解析 - /tools/preprocess_data.py
preprocess_data.py 的主要功能。这是 Megatron-LM 的数据预处理脚本,主要用于将原始文本数据转换为模型训练所需的格式。 核心功能: 1. 数据预处理流程: 输入:原始文本文件(JSON格式) 处理:…...
