- 问题背景 前两天室友问我,怎么 kill 掉在 Shell 脚本中调用的 Python 进程,我第一时间想到的是:打开 htop,把它调整成树形布局,然后搜索 Shell 脚本,选中之后把它 kill 掉,Python 进程应该也会被 kill 掉。 但是结果是 Python 进程并没有变红,而是成为了 init 进程的子进程。 孤儿进程是怎么产生的 大二学 OS 学到父进程和子进程的概念的时候,还是只是以为父进程和子进程之间应该存在牢固的控制关系,父进程退出时子进程也应该默认退出。 但是 OS 的实际行为不是这样,子进程和父进程只是说明了二者之间存在谁创建谁的关系,并不存在牢固的控制关系(而是类似于现实中的父子关系)。 父进程结束时子进程并没有结束,子进程成为孤儿进程,会被 init 进程收养 父进程崩溃或异常终止 并发和竞争条件导致父子进程的结束顺序错误 如何避免孤儿进程的产生 其实就是需要在程序设计时,考虑到上述的这几种可能导致孤儿进程产生的原因,然后对异常情况进行注册和处理。对于开始时的这个引入问题而言,答案可以写成以下两个脚本: #!/bin/bash # 定义一个函数来处理信号 cleanup() { echo "捕捉到终止信号,正在终止 Python 进程..." kill $PYTHON_PID exit } # 在接收到 SIGINT || SIGTERM || SIGKILL 时执行 cleanup 函数 trap 'cleanup' SIGINT SIGTERM # 启动 Python 脚本并获取其进程 ID python example_python.py & PYTHON_PID=$!
- 本文主要记录笔者在 Gentoo Linux 下面搭建 WebRTC 开发环境的过程。 准备工作 网络:可以科学上网的梯子 IDE:VSCode 或者 CLion 安装depot_tools Google 有自己的一套用于管理 Chromium 项目的工具,名叫depot_tools,其中有包括git在内的一系列工具和脚本。 # 创建google目录用于存储google相关的代码 mkdir ~/google cd ~/google # clone depot_tools git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 克隆完成之后需要将depot_tools的路径加到PATH中,Linux 上添加环境变量最简单的方式是修改~/.profile,这种方式与你的登录 shell 是什么没有关系,不管是fish还是bash还是zsh都会吃这种方式: # ~/.profile export GOOGLE_BIN=$HOME/google/depot_tools export PATH=$GOOGLE_BIN:$PATH 但是这种方式需要你注销重新登录。 克隆代码 mkdir webrtc-checkout cd webrtc-checkout fetch --nohooks webrtc gclient sync 整个 WebRTC 的项目代码大小约 20G,克隆过程中需要保证网络畅通顺畅,如果你的梯子有大流量专用节点最好,否则可能克隆完你的流量就用光了。 克隆期间可能会因为网络问题中断,重新执行gclient sync即可,直到所有的模块都克隆完毕。 按照官方的建议,克隆完成之后创建自己的本地分支,因为官方分支更新很快,不 checkout 的话,可能你的 commit 还没写完,就被 Remote 的 change 给覆盖了,还要手动处理冲突。 cd src git checkout master git new-branch <branch-name> 编译 WebRTC 关于 WebRTC 的版本可以在Chromium Dash查到:WebRTC Created
Sun, 23 Apr 2023 21:28:38 +0800 - Overview MLflow是一个用于管理机器学习全生命周期的框架。 其主要的作用是: 完成训练和测试过程中不同超参数的结果的记录、对比和可视化——MLflow Tracking 以一种可复现重用的方式包装 ML 代码——MLflow Projects 简化模型部署的难度——MLflow Models 提供中心化的模型存储来管理全生命周期——MLflow Model Registry 现在主要用到的是第三个,所以先记录Models的用法 MLflow Models MLflow Models本质上是一种格式,用来将机器学习模型包装好之后为下游的工具所用。 这种格式定义了一种惯例来让我们以不同的flavor保存模型进而可以被下游工具所理解。 存储格式 每个MLflow Model是一个包含任意文件的目录,根目录之下有一个MLmodel文件,用于定义多个flavor。 flavor是MLflow Model的关键概念,抽象上是部署工具可以用来理解模型的一种约定。 MLflow定义了其所有内置部署工具都支持的几种标准flavor,比如描述如何将模型作为Python函数运行的python_function flavor。 目录结构示例如下: MLmode文件内容示例如下: 这个模型可以用于任何支持pytorch或python_function flavor的工具,例如可以使用如下的命令用python_function来 serve 一个有python_function flavor的模型: mlflow models serve -m my_model Model Signature 模型的输入输出要么是column-based,要么是tensor-based。 column-based inputs and outputs can be described as a sequence of (optionally) named columns with type specified as one of the MLflow data type. tensor-based inputs and outputs can be described as a sequence of (optionally) named tensors with type specified as one of the numpy data type.ML Created
Mon, 07 Mar 2022 19:25:46 +0800 - 最近几天一直在用WebXR的技术重构目前的基于分块的全景视频自适应码率播放客户端,下面简述一下过程。 首先结论是:分块播放+自适应码率+完全的沉浸式场景体验=Impossible(直接使用 WebXR 提供的 API) 分块播放 分块播放的本质是将一整块的全景视频从空间上划分成多个小块,各个小块在时间上与原视频的长度是相同的。 在实际播放的时候需要将各个小块按照原有的空间顺序排列好之后播放,为了避免各个分块播放进度不同的问题,播放时还需要经过统一的时间同步。 对应到 web 端的技术实现就是: 一个分块的视频<->一个<video>h5 元素<->一个<canvas>h5 元素 视频的播放过程就是各个分块对应的<canvas>元素不断重新渲染的过程 各个分块时间同步的实现需要一个基准视频进行对齐,大体上的原理如下: let baseVideo = null; let videos = []; initBaseVideo(); initVideos(); for (video in videos) { video.currentTime = baseVideo.currentTime; } 自适应码率 自适应码率的方案使用dashjs库实现,即对每个分块<video>元素的播放都用dashjs的方案控制: import { MediaPlayer } from "dashjs"; let videos = []; let dashs = []; let mpdUrls = []; initVideos(); initMpdUrls(); for (let i = 0; i < tileNum; i++) { let video = videos[i]; let dash = MediaPlayer().WebXR Created
Fri, 25 Feb 2022 11:04:23 +0800