分类 技术 下的文章

这是一个循序渐进的初学者教程,展示了如何在 Xubuntu 和其他使用 Xfce 桌面环境的 Linux 发行版中安装主题和图标。

在 Xubuntu 上安装主题与 Ubuntu 或其他 Linux 发行版类似。你把主题文件放在 ~/.themes 文件夹中,然后用一个工具来改变它。

然而,考虑到 Xubuntu 使用 Xfce 桌面环境,一些选项或用户界面看起来会有所不同。这就是为什么我创建了这个教程,用适当的截图来展示步骤。

在 Xubuntu(Xfce)中安装新主题

开始前,你需要在主目录下创建一个 .themes 文件夹。注意文件夹名称前的点(.)。它很重要,可以从正常的视图中隐藏该文件夹。

要检查你是否已经有了它,你可以 启用查看隐藏文件,然后在它不存在的时候创建它。

完成后,你需要下载一个主题。

1、你可以在 Xfce-look 门户网站上浏览 XFCE 主题。你所要做的就是下载存档(压缩)文件。

2、接下来,你需要 解压缩文件,如下面的截图所示。

3、解压后,你会发现出现一个文件夹,你要复制它。

4、然后你要把这个文件夹粘贴到你最初创建的 .themes 目录中。

5、最后,你需要到外观设置中找到它,并选择它/应用它以使其生效。

正如你在下面的截图中注意到的,新的主题已经被添加和应用:

除了主题之外,如果你需要定制你的 Xubuntu 桌面的图标,你需要在主目录中创建另一个 .icons 文件夹。

就像你安装主题一样,你将不得不遵循一个类似的过程来应用图标主题。

为了给你一个例子,让我在这里强调这些步骤:

在 Xubuntu(Xfce) 中添加图标主题

你可以浏览同样的 xfce-look portal 来寻找完整的图标主题。

或者,你可以寻找一些最好的 可用于 Ubuntu 的图标主题,它们应该也适用于 Xubuntu。

一旦你找到了你喜欢的,就下载它,并按下面的方式解压。

接下来,你需要把这个文件夹复制并粘贴到 .icons 文件夹中。

现在,你可以回到外观设置中,找到列在“图标”下的可用图标。

为了向你展示区别,我把默认的 Xubuntu 主题改为 adwaita-dark,你可以在这里看到:

注意:一些图标或主题文件可能包含有不同变体的嵌套文件夹。你会注意到它们并没有出现在外观工具中。如果是这种情况,直接将内部文件夹复制到 ~/.themes~/.icons 文件夹中。

总结

通过对风格和图标的调整,你可以 定制你的 Xubuntu 体验 以融入你的品味。

你是喜欢默认的 Xubuntu 外观还是使用不同的主题/图标来定制它的外观?请在评论中告诉我你的想法。


via: https://itsfoss.com/install-themes-xfce-xubuntu/

作者:Ankush Das 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

有很多 基于 Linux 的笔记本电脑,也有 预装了 Linux 的迷你 PC,而市场上还有一些 基于 Linux 的智能手机

那平板电脑呢?有没有一些不错的基于 Linux 的平板电脑?这可能不能用一句话说清楚。

许多仅使用 Linux 的系统制造商专注于制造台式电脑。这主要是由于触摸设备上的 Linux 体验与安卓和 iOS 提供的体验相距甚远。

但这是否意味着你不能在平板电脑上使用 Linux?并非如此。对于早期尝试用户和 DIY 爱好者来说,还有一些选择的。让我们来看看在这些 Linux 平板电脑中,你有哪些选择。

Ubuntu Touch

BQ 平板电脑上的 Ubuntu Touch 操作系统

好吧!这不是一个平板电脑,而是一个操作系统。但它确实让你可以在一些旧的安卓平板电脑上安装一个适合触摸操作的 Ubuntu 版本。

注意“一些”这个词。Ubuntu Touch 官方 支持 Nexus 7、联想 M10、Xperia Z4 和 BQ Aquaris 平板。你甚至可以尝试在你的其他平板电脑上安装 Ubuntu Touch。它可能无法 100% 工作,但仍然非常有用。

Ubuntu Touch 是 Ubuntu 团队的一个项目,但是他们 在 2017 年中止了它UBports 承担了继续这个项目的责任,他们在有限的资源下做的很棒。

总而言之,如果你喜欢各种实验,想让你的旧安卓平板电脑获得新生,Ubuntu Touch 可能是你的周末项目。

PineTab

PineTab

Pine64 始于其单板计算机 Pine A64,以作为 树莓派的替代品。随着时间的推移,它推出了几个 Pine 品牌的产品。这份名单里包括低调的 PineTime 智能手表、PineBook 笔记本电脑、PinePhone 智能手机和 PineTab 平板电脑。

这些 Pine 设备通常价格低廉,并允许用户对这些小设备进行完全控制。这种可魔改的特性帮助它聚集了一大批开源 DIY 爱好者的粉丝。

PineTab 基本上使用了与带有触摸屏和键盘的 Pine64 单板计算机相同的组件。它不是看起来最漂亮的平板电脑,也不打算成为这样的。

它的规格很一般,有一个高清 IPS 电容式触摸屏、全志 A64 芯片组、四核 CPU 和 2GB 内存。

它无法与 iPad 或 Galaxy Tab 竞争,但它允许你安装你选择的发行版,并按你的要求进行配置。

请记住,Pine 的库存有限,所以如果你能看到这个设备可以购买,那你很幸运。

PineNote

PineNote

另一个 Pine 设备,与你在上一节看到的 PineTab 略有不同。

PineTab 是一款用于浏览互联网、使用应用程序和玩游戏的 Linux 平板电脑,而 PineNote 是用来做笔记和阅读书籍和文件的。

它有一个电子墨水显示屏,你可能在 Kindle 等电子书阅读器上见过。除了电子书阅读器之外,PineNote 还可以你用 Wacom 笔做笔记。

PineNote 拥有四核 Rockchip、多点触控电子墨水面板、4GB 内存和 128GB eMMC 存储。它也是为数不多的价格高于通常的 399 美元的平板点之一。

请记住,PineNote 正处于早期开发阶段,只接受开发者的订单。

RasPad

RasPad

RasPad 是一个用于树莓派设备的套件,可以把它变成一个基于触摸功能的设备。与普通的平板不同,这不是一个扁平的设备,而是有一个楔形的身体。这使得它更容易在办公桌上使用。

RasPad 是专门为树莓派设备创建的,你可以轻松使用它的大部分端口。它有一个专门的 RasPad 操作系统,但你可以自由使用常规的树莓派操作系统或 Ubuntu 或任何其他适合树莓派的操作系统。在选择操作系统时请考虑触控友好性。

请记住,树莓派设备不包括在套件中。你必须要单独购买。

你的选择是什么?

我知道我们离一个优秀的 Linux 平板电脑还很远,但它们至少可以和市场上的安卓平板电脑竞争。至少我们有一些可用的选择,这也是一线希望。

你是否已经拥有以上列出的设备之一了?你的体验如何?

如果你只能选择其中之一,那么你选择哪一款 Linux 平板电脑?


via: https://itsfoss.com/linux-tablets/

作者:Abhishek Prakash 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

当你将某些资源存档或用于教育目的时,将网页保存为 PDF 是很方便的。

但是,你如何在 Linux 中把一个网页转换成 PDF?

你可以选择使用每个 Linux 发行版上的网页浏览器(GUI),或者使用终端将网页变成 PDF 文件。

在这里,我将提到这两种方法来帮助你完成工作。

方法 1:使用网页浏览器将网页转换为 PDF 文件

尽管我在本教程中使用的是 Mozilla Firefox,但你也可以用任何 可用于 Linux 的最佳浏览器 做同样的事情。

1、加载你想转换的网页。

2、在浏览器菜单中找到“打印”选项,或使用键盘快捷键 Ctrl + P

3、默认情况下,它应该让你把它保存为 PDF。你需要点击“保存”,然后选择目的地并保存网页。

Save webpage as PDF in Mozilla Firefox

这种简单方法的一个主要问题是,它包括页面上的所有元素。这可能包括评论、页脚等。你可以用一个 PDF 编辑器来删除部分内容,但这是一个额外的任务。

更好的选择是利用一个浏览器扩展,如 Print Friendly。它允许你在下载 PDF 之前编辑和删除网页的部分内容。

方法 2:使用终端将网页转换为 PDF 或图片

你可能已经知道,你可以 在 Linux 终端浏览互联网,甚至 使用命令行下载文件。这并不奇怪,因为你可以在终端中做更多的事情,包括将网页下载为 PDF。

一个灵巧的开源命令行工具 wkhtmltopdfwkhtmltoimage 可以帮到你,让你把任何 HTML 网页转换成 PDF 或图像文件。

它使用 Qt WebKit 渲染引擎来完成这个任务。你可以浏览它的 GitHub页面 了解更多信息。

你应该能够从你的 Linux 发行版的默认仓库中安装它。对于基于 Ubuntu 的发行版,你可以输入以下命令:

sudo apt install wkhtmltopdf

无论你想把它转换为 PDF 还是图像文件,它的使用都是非常直接的:

要将一个网页转换成 PDF,请输入:

wkhtmltopdf URL/domain filename.pdf

比如,类似于这样:

wkhtmltopdf linuxmint.com mint.pdf

你可以选择使用 https://linuxmint.com 这样完整的 URL 或使用域名,如上面的例子所示。

默认情况下,生成的文件将保存在主目录下。

在转换网页时,你还可以得到一些好玩的选项。

例如,你可以对 PDF 文件应用灰度过滤器,在同一文件中制作多个页面副本,以及在转换过程中排除图像。

灰度过滤器不一定对每个网页都有效,但你可以用命令试试:

wkhtmltopdf -g google.com googlepage.pdf

要在同一个 PDF 文件中复制多个页面,命令是:

wkhtmltopdf --copies 2 linuxmint.com mint.pdf

而且,如果你想排除网页中的图像,只需输入:

wkhtmltopdf --no-images linuxmint.com mint.pdf

此外,如果你想把一个网页转换为图像,命令是这样的:

wkhtmltoimage linuxmint.com mint.png

注意,与使用浏览器的 GUI 方法不同,通过终端使用这些工具有其局限性。它似乎不能成功转换利用任何 <iframe> 代码片段的网页。

像我们的网站,甚至 DuckDuckGo 都没有转换为 PDF 或图像。然而,简单的 HTML 网站,如 Linuxmint.comUbuntu.comGoogle.com 则非常有效。

总结

使用浏览器将网页保存为 PDF 似乎是个好办法。但是,如果你想有更多的选择并通过终端,wkhtmltopdf 工具应该会派上用场。

你喜欢如何在 Linux 中把网页转换为 PDF?欢迎在评论中分享你的想法。


via: https://itsfoss.com/convert-webpage-pdf-linux/

作者:Ankush Das 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

2021 国庆前一天,欧拉操作系统按照既定的半年发布一个创新版本的节奏,发布了第三个创新版本 openEuler 21.09。在前不久召开的“华为全连接 2021 大会”上,我听到了欧拉即将进行“全新”发布的消息。作为一名长期观察欧拉发展的业内人士,我对这“全新”的说法是好奇的,这究竟是一种宣传的手法,亦或是真的有了很大不同?

怀着这个疑问,我对在“华为全连接 2021”后几天发布的 openEuler 21.09 是颇为关注的,希望可以第一时间拿到它的白皮书一窥究竟。几天后,欧拉发布了该版本的技术白皮书。我在翻阅后感觉,与其说欧拉是一辆粉饰一新的新车,不如说是它在引擎盖下做了颇多改进。

在这份几十页的《openEuler 21.09 技术白皮书》,颇有一些值得重视的技术变化被掩盖在了枯燥的技术术语之中,因此,本着一飨读者的想法,我对其中值得关注的地方,用更浅显的语言进行了一些解读。

openEuler 发布

首先回顾一下欧拉的基本情况。欧拉最初脱胎于华为内部的 Linux 发行版 EulerOS,后于 2019 年底宣布开源,成为 openEuler。其主要面对的是服务器基础设施领域,并在次年春季发布了第一个 LTS 版本。欧拉的主要技术路线沿袭了红帽系的技术方向,无论是从软件包管理、文件系统布局、操作系统体验方面,都吸收了不少 CentOS/RHEL 惯例。但是,欧拉又不是一个 CentOS 的某个版本的下游分支版本,因为其从内核、特性、技术演进方向,都有自己的独立而确定的发展计划,这一点和 SUSE 公司的 openSUSE/SLES 发行版家族类似。

欧拉采用了定期发布版本的发行计划,每两年发布一个长期支持版本(LTS)。除了作为服务器操作系统所重视的长期支持和特性稳定之外,欧拉也是一个技术孵化器,它每半年发布一次的创新版,集成了社区的最新技术成果,将社区验证成熟的特性逐步回合到发行版中。从 2020 年 3 月发布第一个 LTS 版本之后,它已经发布了三个创新版本,按照计划,下一个 LTS 版本将于 2022 年 3 月到来。

openEuler 版本图

如上所述,这次发布的 21.09 是一个创新版本,主要是迭代演进即将放入到下一个 LTS 版本中的新特性。在这个版本中,重点引入和发展的特性有:

  • 内核的创新:新介质文件系统和内存分级扩展
  • 云原生创新:容器操作系统、安全容器和双平面部署
  • 增强的特性:对语言编译器的支持、对运维的支持
  • 全场景创新:对编译计算、嵌入式场景的支持和集群加速引擎

下面,我们就这些特性展开来了解一下。

白话解析白皮书

如果不是欧拉社区的相关贡献者和长期参与者,你可能会觉得这份技术白皮书有些难读。我也是这样觉得的,不过,进行梳理之后,我把这几十页的内容凝聚成了几个关键字:内核特性容器技术架构支持场景支持

内核特性

Linux 系统给你的感受是什么?可能有很多答案,但是归根到底,这是一幢建立在 Linux 内核基础之上的华厦。内核提供的各种新特性,通过上层的应用最终提供了各种公用。因此,一个 Linux 操作系统的根本就是内核。

说句题外话,国内流行的 CentOS,主要的原因还是大家信任它的内核。这一点,谁做过运维谁知道。而华为作为国内首屈一指的在 Linux 内核方面颇有建树的企业,这些年来,在 Linux 内核方面已经做出了诸多贡献。

内核贡献图

华为在芯片架构、ACPI、内存管理、文件系统、介质、内核文档、内核质量加固及代码重构等方面,十余年来总计向社区贡献 17000+ 个补丁。而在 Linux 内核 5.10 和 5.14 版本中,欧拉内核研发团队代码贡献量排名全球第一。

那么我们来看看具体在这个版本中,欧拉在内核方面做了什么努力。

欧拉 21.09 还是基于 Linux 内核 5.10 构建,但在进程调度、内存管理、网络等方面带来了 12 处创新,这主要有:用来提升性能的进程调度优化、大页内存性能优化、OOM 内存回收优化、XDP 网络性能优化等。

除了这些隐蔽但重要的内核改进之外,如今在运维领域已经大量使用的非易失性内存(NVDIMM)存储介质,在使用传统的 ext4 文件系统时,尚缺乏针对性的优化,因为 Ext4 本身是针对旋转式硬盘设计的文件系统。尤其在元数据管理方面,基于现有日志同步机制,元数据管理开销大,且容易出现写放大问题,NVDIMM 优势无法充分发挥。华为推出的 Eulerfs 创新的元数据软更新技术,减少了元数据同步开销,有效提升文件系统的系统调用性能。在单机应用、云原生分布式应用高性能数据存储场景,可以代替 Ext4、XFS 等文件系统。

容器技术

现在的运维领域,几乎是言必称云原生。一个操作系统的对云原生、虚拟化的支持力度,也成了一种试金石。

欧拉面向云原生业务混合部署场景提出了一种 QAS 算法。它是一种适用于云原生场景,业务混合部署的全新调度算法,可以确保在线任务对 CPU 的快速抢占,确定性的调度运行,同时压制离线任务干扰。此外,在欧拉中还优化了 OOM(内存使用超量)时内存回收调度算法,在发生 OOM 时,优先对低优先级的进程组进行内存回收,保障在线业务的正常运行。这些改进适用于对交互类等时延敏感型业务(比如 MySQL、Redis、Nginx 等)和 CPU 消耗重且时延不敏感的业务(如 AI 离线训练)混合部署,它包括了容器与容器、容器与进程、容器与虚机、虚机与虚机等多种混合部署场景。

Kubernetes 已经成为事实上的云原生软件基础设施底座。业界的主流操作系统厂商都推出了针对云原生场景的操作系统。欧拉自然也不甘人后,推出了容器化操作系统 KubeOS,实现云原生集群操作系统的统一容器化管理。它可以对操作系统容器化管理、对接 Kubernetes、原子化的生命周期管理;它也对操作系统进行了轻量化裁剪,减少不必要的冗余包,可实现系统的快速升级、替换等。

再往底层看,欧拉结合虚拟化运行时 StratoVirt、容器管理引擎 iSulad 构建了安全容器方案,较之传统的 Docker + Qemu 方案,其底噪和启动时间优化高达 40% 以上,为应用提供了一个轻量、安全的执行环境,隔离了容器和宿主机操作系统间、容器间的安全风险。

架构支持

针对不同的硬件架构,欧拉在编程语言和架构方面还做了支持。

欧拉提供的毕昇 JDK 是基于 OpenJDK 开发的增强版本,具备高性能、高可用等优点,可用于生产环境。值得一提的是,它积累了大量使用场景,并针对 ARM 进行了性能优化。毕昇 JDK 支持 OpenJDK 8 和 OpenJDK 11 两个版本。

在欧拉中也有鲲鹏处理器打造的高性能编译器,Kunpeng GCC 编译器是基于 GCC 开发的,可以充分发挥鲲鹏的硬件特性,运行效率更高。

据测试,毕昇 JDK 在 SPECjbb2015 等基准测试中性能优于 OpenJDK。Kunpeng GCC 编译器在 SPEC CPU 2017 等基准测试中性能大幅优于上游社区的 GCC 10.3 版本。欧拉最初就是针对华为鲲鹏硬件架构开发的操作系统,因此,在欧拉中自然提供了针对性的优化,以充分发挥鲲鹏服务器硬件特性,这也算是应有之义。

在这次发布中,华为还重点提及,欧拉最初是作为对鲲鹏硬件的支持出现的,但是现在已经扩展到支持 x86、ARM、RISC-V 等多处理器架构,未来还会扩展 PowerPC、SW64 等更多芯片架构支持。但是从白皮书中,我们尚没有看到对其它处理器架构的特定优化工作和测试数据。

场景支持

从白皮书中我们看到,欧拉现在从对服务器场景的应用,逐步拓展到云计算、边缘计算、嵌入式等更多场景,正成为覆盖全场景的操作系统。

欧拉透露,它将发布面向边缘计算的版本 openEuler 21.09 Edge 和面向嵌入式的版本 openEuler 21.09 Embedded。这两个针对不同场景的版本突破了原有的服务器基础设施领域,但是,从我了解到的情况看,这其实已经不是 Linux 内核为基础的操作系统了,而是基于华为本身在这些领域的内核及应用开发的。可以理解为在一个统一的框架下的不同内核、不同操作系统。

欧拉的多场景支持

当然,除此以外,在这次发布的欧拉 21.09 中,还有很多具体方向的创新和改进,感兴趣的同学可以获取这份技术白皮书以了解究竟。

结语

每半年发布的一个创新版,我认为并不是很适合于需要特性稳定的产品环境部署,但是通过这些创新版本,社区和相关生态的企业可以提前针对新的特性进行开发、测试和优化。而无论是服务器环境,还是嵌入式、边缘技术,都需要一个具备稳定性、高性能、精细调优的操作系统,这就是明年 3 月将发布的下一个 LTS 版本的目标。而且,除了长期支持以外,我们可以期待在创新版中发布的新特性,也会经过打磨后融入到 LTS 版本中。

当然,我认为,LTS 版本并不是一个口号,而是需要真正地提供支持和维护。这是一种并不像发布新版本那么令人激动的工作,但是这种持续的支持,才是一个企业级的操作系统的根本。我们期望看到欧拉能够践行其对技术创新和长期支持的承诺和落实。


想要进一步了解这份《openEuler 21.09 技术白皮书》,可以点击此处下载

Rust 的高性能、高可靠性和高生产力使它适合于嵌入式系统。

 title=

在过去的几年里,Rust 在程序员中获得了热情的追捧。技术潮流来来去去,所以很难将仅仅因为某项新技术而产生的兴奋与对某项技术的优点的兴奋区分开来,但我认为 Rust 是一种真正设计良好的语言。它的目标是帮助开发者建立可靠和高效的软件,而且它从一开始就是为这个目的设计的。你可能听过一些 Rust 的关键特性,在这篇文章中,我会证明这些特性正是 Rust 也恰好适合嵌入式系统的原因。比如:

  • 高性能:它速度快,内存利用率高
  • 可靠性:在编译过程中可以消除内存错误
  • 生产力:很棒的文档,友好的编译器,有用的错误信息,以及一流的工具化。它有一个集成的包管理器和构建工具,智能的多编辑器支持自动补完和类型检查、自动格式化等等。

为什么使用 Rust 进行嵌入式开发?

Rust 的设计是为了保证安全和高性能。嵌入式软件会出现的问题主要是内存的问题。从某种程度上说,Rust 是一种面向编译器的语言,所以你可以确保在编译时安全使用内存。以下是使用 Rust 在嵌入式设备上开发的一些好处:

  • 强大的静态分析
  • 灵活的内存
  • 无畏的并发性
  • 互操作性
  • 可移植性
  • 社区驱动

在这篇文章中,我使用开源的 RT-Thread 操作系统 来演示如何使用 Rust 进行嵌入式开发。

如何在 C 语言中调用 Rust

在 C 代码中调用 Rust 代码时,你必须将 Rust 源代码打包成静态库文件。当 C 代码编译时,将其链接进去。

用 Rust 创建一个静态库

在这个过程中,有两个步骤:

1、使用 cargo init --lib rust_to_c 在 Clion 中建立一个 lib 库。在 lib.rs 中加入以下代码。下面的函数计算两个类型为 i32 的值的总和并返回结果:

#![no_std]
use core::panic::PanicInfo;

#[no_mangle]
pub extern "C" fn sum(a: i32, b: i32) -> i32 {
    a + b
}

#[panic_handler]
fn panic(_info:&PanicInfo) -> !{
    loop{}
}

2、在你的 Cargo.toml 文件中添加以下代码,以告诉 Rustc 要生成什么类型的库:

[lib]
name = "sum"
crate-type = ["staticlib"]
path = "src/lib.rs"

交叉编译

你可以针对你的目标平台进行交叉编译。假设你的嵌入式系统是基于 Arm 的,步骤很简单:

$ rustup target add armv7a-none-eabi

生成静态库文件:

$ cargo build --target=armv7a-none-eabi --release --verbose
Fresh rust_to_c v0.1.0
Finished release [optimized] target(s) in 0.01s

生成头文件

你也需要头文件:

1、安装 cbindgencbindgen 工具会从 Rust 库中生成一个 C 或 C++11 的头文件:

$ cargo install --force cbindgen

2、在你的项目文件夹下创建一个新的 cbindgen.toml 文件。

3、生成一个头文件:

$ cbindgen --config cbindgen.toml --crate rust_to_c --output sum.h

调用 Rust 库文件

现在你可以对你的 Rust 库进行调用了。

1、把生成的 sum.hsum.a 文件放到 rt-thread/bsp/qemu-vexpress-a9/applications 目录下。

2、修改 SConscript 文件并添加一个静态库:

   from building import *
   
   cwd     = GetCurrentDir()
   src     = Glob('*.c') + Glob('*.cpp')
   CPPPATH = [cwd]
   
   LIBS = ["libsum.a"]
   LIBPATH = [GetCurrentDir()]
   
   group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH, LIBS = LIBS, LIBPATH = LIBPATH)
   
   Return('group')

3、在主函数中调用 sum 函数,得到返回值,并 printf 该值:

   #include <stdint.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <rtthread.h>
   #include "sum.h"
   
   int main(void)
   {
       int32_t tmp;
   
       tmp = sum(1, 2);
       printf("call rust sum(1, 2) = %d\n", tmp);
   
       return 0;
   }

4、在 RT-Thread Env 环境中,使用 scons 来编译项目并运行:

$ scons -j6
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
[...]
scons: done building targets.

$ qemu.sh
 \ | /
- RT -     Thread Operating System
 / | \     4.0.4 build Jul 28 2021
2006 - 2021 Copyright by rt-thread team
lwIP-2.1.2 initialized!
[...]
call rust sum(1, 2) = 3

加、减、乘、除

你可以在 Rust 中实现一些复杂的数学运算。在 lib.rs 文件中,使用 Rust 语言来实现加、减、乘、除:

#![no_std]
use core::panic::PanicInfo;

#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[no_mangle]
pub extern "C" fn subtract(a: i32, b: i32) -> i32 {
    a - b
}

#[no_mangle]
pub extern "C" fn multiply(a: i32, b: i32) -> i32 {
    a * b
}

#[no_mangle]
pub extern "C" fn divide(a: i32, b: i32) -> i32 {
    a / b
}

#[panic_handler]
fn panic(_info:&PanicInfo) -> !{
    loop{}
}

构建你的库文件和头文件,并把它们放在应用程序目录中。使用 scons 来编译。如果在链接过程中出现错误,请在官方 Github 页面 中找到解决方案。

修改 rtconfig.py 文件,并添加链接参数 --allow-multiple-definition

       DEVICE = ' -march=armv7-a -marm -msoft-float'
       CFLAGS = DEVICE + ' -Wall'
       AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__ -I.'
       LINK_SCRIPT = 'link.lds'
       LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors,--allow-multiple-definition'+\
                         ' -T %s' % LINK_SCRIPT
   
       CPATH = ''
       LPATH = ''

编译并运行 QEMU 来看看你的工作。

在 Rust 中调用 C 语言

Rust 可以在 C 代码中调用,但是如何在你的 Rust 代码中调用 C 呢?下面是一个在 Rust 代码中调用 rt_kprintf C 函数的例子。

首先,修改 lib.rs 文件:

    // The imported rt-thread functions list
    extern "C" {
        pub fn rt_kprintf(format: *const u8, ...);
    }
   
    #[no_mangle]
    pub extern "C" fn add(a: i32, b: i32) -> i32 {
        unsafe {
            rt_kprintf(b"this is from rust\n" as *const u8);
        }
        a + b
    }

接下来,生成库文件:

$ cargo build --target=armv7a-none-eabi --release --verbose
Compiling rust_to_c v0.1.0
Running `rustc --crate-name sum --edition=2018 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type staticlib --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no -C metadata=a
Finished release [optimized] target(s) in 0.11s

而现在,要运行代码,将 Rust 生成的库文件复制到应用程序目录中,然后重新构建:

$ scons -j6 scons: Reading SConscript files ... scons: done reading SConscript files. [...]
scons: Building targets ... scons: done building targets.

再次运行 QEMU,可以在你的嵌入式镜像中看到结果。

你可以拥有这一切

在你的嵌入式开发中使用 Rust,你可以获得 Rust 的所有功能,而不需要牺牲灵活性或稳定性。今天就在你的嵌入式系统上试试 Rust 吧。关于嵌入式 Rust 的过程(以及 RT-Thread 本身)的更多信息,请查看 RT-Thread 项目的 YouTube 频道。请记住,嵌入式也可以是开放的。


via: https://opensource.com/article/21/10/rust-embedded-development

作者:Alan Smithee 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这是一个关于如何寻找 Linux 系统僵尸进程并杀死它们的小知识。你也可以从中了解到关于进程和僵尸进程的一些知识。

在了解僵尸进程之前,让我们来复习一下什么是 Linux 进程。

简而言之,进程 是一个程序的运行实例。它可能运行在前端(比如有交互的进程),也可能运行在后端(比如无交互或自动运行的进程)。它可能是一个父进程(运行期间创建了其他进程),也可能是一个子进程(由其他进程所创建)。

在 Linux 系统中,除 PID 为 0 的第一个 init 进程(或 systemd)外,其余进程都有父进程。进程也可以拥有自己的子进程。

不相信?可以试试在终端中使用 pstree 命令查看进程的树型结构,你能看到系统各个进程的“家族树”。

Linux系统里的僵尸进程是什么?

子进程死亡后,它的父进程会接收到通知去执行一些清理操作,如释放内存之类。然而,若父进程并未察觉到子进程死亡,子进程就会进入到“ 僵尸 zombie ”状态。从父进程角度看,子进程仍然存在,即使子进程实际上已经死亡。这就是“ 僵尸进程 zombie process ”(也被称为“ 已消失进程 defunct process ”)是如何产生并存在于系统中的。

这里有一个来自 Turnoff.us 的关于僵尸进程的非常有趣的看法:

Image credit: Turnoff.us

你真的需要关心僵尸进程吗?

重点要说的是,僵尸进程并没有像它的名称那样看起来可怕。

但如果系统的内存已经所剩不多或者有太多的僵尸进程在吃掉内存,问题会变得糟糕。同样,大部分 Linux 系统进程最大 PID 设置为 32768,如果过多僵尸进程导致其他重要任务没有 PID 可用,你的系统会发生崩溃。

这是真实可能发生的,它有一定的概率,特别当存在一个编码糟糕的程序开始大量产生僵尸进程的时候。

在这种情况下,找到并杀死僵尸进程是一个明智的做法。

如何找到僵尸进程

Linux 系统中的进程可能处于如下状态中的一种:

  • D = 不可中断的休眠
  • I = 空闲
  • R = 运行中
  • S = 休眠
  • T = 被调度信号终止
  • t = 被调试器终止
  • Z = 僵尸状态

那如何查看进程和它的当前状态呢?一个简单的方法是在终端中使用 top 命令

Top command show processes and their status

正如你在上面截图中看到的,截图中共有 250 个任务(进程),其中 1 个处在 “ 运行中 running ” 状态,248 个进程处于 “ 休眠 sleep ” 状态,还有一个处于 “ 僵尸 zombie ” 状态。

现在问题进入下一步,如何杀死 “僵尸” 进程?

如何找到并杀死一个僵尸进程?僵尸进程能被杀死吗?

僵尸进程已经死了,要如何才能杀死一个已经死亡的进程呢?

在僵尸电影中,你可以射击僵尸的头部或烧掉它们,但在这里是行不通的。你可以一把火烧了系统来杀死僵尸进程,但这并不是一个可行的方案。

一些人建议发送 SIGCHLD 给父进程,但这个信号很可能会被忽略。还有一个方法是杀死父进程来杀死僵尸进程,这听起来很野蛮,但它却是唯一能确保杀死僵尸进程的方法。

首先,通过在终端中 使用 ps 命令 我们列举僵尸进程,得到它们的进程 ID:

ps ux | awk '{if($8=="Z+") print}'

ps ux 命令输出的第 8 列显示了进程状态。上述命令只会打印所有处在 Z+ 状态(表示僵尸状态)的进程。

确认了进程 ID 后,我们可以得到它的父进程 ID:

ps -o ppid= -p <child_id>

你也可以将上述两个命令结合在一起,直接得到僵尸进程的 PID 及其父进程的 PID:

ps -A -ostat,pid,ppid | grep -e '[zZ]'

现在你得到了父进程 ID,使用命令行和得到的 ID 号 终于可以杀死进程了

kill -9 <parent_process_ID>

Killing parent process

再次运行 ps 命令或 top 命令,你可以验证僵尸进程是否已经被杀死。

恭喜!现在你知道怎么清理僵尸进程了。


via: https://itsfoss.com/kill-zombie-process-linux/

作者:Marco Carmona 选题:lujun9972 译者:zengyi1001 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出