当前位置: 首页 > news >正文

[OS] 终端控制(Terminal Control) 暂停执行线程(Suspend Executing Thread)

7. 终端控制(Terminal Control)

在终端中打印信息时,我们可以使用 ANSI 转义序列来控制光标的位置、清除屏幕等操作。\033 是转义字符,用于引导 ANSI 控制码来控制终端显示。可以将它理解为“命令前缀”,后面跟着具体的指令代码来控制终端的行为。

7.1 示例代码:使用 \033 控制终端光标和屏幕

以下是一个示例代码,展示如何使用 \033 来清屏、控制光标位置,并在屏幕上打印信息。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main(int argc, char *argv[]) {int isStop;// 清屏printf("\033[2J");// 在不同位置打印信息for (isStop = 1; isStop < 11; isStop++) {// 设置光标位置:移动到 (11 - isStop) 行的第 10 列printf("\033[%d;10H", (11 - isStop));printf("Printing within loop %d!\n", isStop);sleep(1);  // 等待 1 秒}// 移动光标到左上角并清除屏幕printf("\033[H\033[2J");return 0;
}
代码解释
  1. 清除屏幕

    • printf("\033[2J");
      • \033[2J:清除整个屏幕。\033 是转义字符,[2J 是清除屏幕的命令。
  2. 设置光标位置并打印信息

    • printf("\033[%d;10H", (11 - isStop));
      • \033[%d;10H:将光标移动到指定的位置。
      • %d 表示行号,这里 (11 - isStop) 是动态计算行号,10 是列号。这样可以让打印的信息从屏幕的第 11 行开始依次向上打印。
  3. 等待

    • sleep(1);
      • 通过 sleep(1) 使程序在每次循环时等待 1 秒,这样每次打印可以有明显的时间间隔。
  4. 结束时再次清屏

    • printf("\033[H\033[2J");
      • \033[H:将光标移动到屏幕的左上角(第 1 行,第 1 列)。
      • \033[2J:清除整个屏幕。

输出效果

当运行这个程序时,你会看到以下行为:

  1. 程序开始时,屏幕会被清除。
  2. 在每次循环中,程序会将光标定位到一个新的位置(行号逐渐减小,但列号保持不变),并打印信息。例如:

    Printing within loop 1! Printing within loop 2! ...

    信息每次会从屏幕的不同位置打印,每次向上移动一行。
  3. 每次打印后会等待 1 秒,这样可以看到打印过程是逐行向上的。
  4. 循环结束后,屏幕会再次被清除。

\033 控制序列的常用命令

  • \033[H:将光标移动到屏幕左上角(第 1 行,第 1 列)。
  • \033[2J:清除屏幕内容。
  • \033[n;mf:设置文本颜色,其中 n 是颜色代码。
    • 例如:\033[31m 将文本设置为红色。
  • \033[nA:将光标向上移动 n 行。
  • \033[nB:将光标向下移动 n 行。
  • \033[nC:将光标向右移动 n 列。
  • \033[nD:将光标向左移动 n 列。

通俗解释

可以把使用 \033 控制终端显示比作是写黑板时控制粉笔的位置。\033 是控制粉笔移动的指令,通过指定行和列的坐标来移动粉笔,让它在指定的位置书写。

在终端应用中,这种控制非常有用,例如:

  • 实现命令行界面中的进度条
  • 更新输出的状态信息而不清屏。
  • 实现动态显示的内容,比如一个简单的文本游戏或用户交互的应用程序。

为什么需要这些控制字符?

  • 动态输出:使用控制字符可以实现屏幕上信息的动态更新,而不是每次都打印新的内容。这对于游戏、实时监控程序等非常有用。
  • 改善用户体验:可以避免在终端中打印过多信息,让输出更加有条理。通过控制光标位置,可以实现更直观的输出形式,例如进度条、状态更新等。

示例应用场景

  • 游戏:像贪吃蛇这样的终端游戏,可以使用光标控制来实现蛇的移动,而不是不断刷新整个屏幕。
  • 实时监控:在显示一些实时数据(如 CPU 使用率、内存占用等)时,可以直接在原来的位置更新数据,而不是一行一行地追加输出。
  • 命令行界面:例如用于选择菜单选项、进度指示器等。

总结

  • \033 是 ANSI 控制序列的起始符号,用于向终端发送控制命令。
  • 通过使用 控制字符,可以更好地控制终端上的光标位置、文本颜色、清屏等功能,从而实现更复杂的显示效果。
  • 使用这些控制字符可以使终端程序更加交互和友好,在开发游戏、监控工具、动态显示工具时非常有用。

8. 暂停执行线程(Suspend Executing Thread)

usleep(useconds_t usec) 函数用于暂停线程的执行,单位是微秒。它可以让线程暂停指定的时间,然后再继续执行。这种功能非常有用,例如控制任务的执行节奏或使线程在等待某些条件时休眠。

  • usleep():用于暂停调用线程指定的微秒数(1 秒 = 1,000,000 微秒)。
  • sleep():用于暂停线程指定的秒数。
  • nanosleep():用于以纳秒精度指定休眠时间。适合需要更高精度的时间控制的场合。

8.1 示例代码:使用 usleep()sleep()

以下是一个简单的示例,展示如何使用 sleep()usleep() 来控制程序的执行。

示例代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>int main(int argc, char *argv[]) {// 使用 sleep() 函数暂停程序执行 5 秒printf("Sleep program for 5 seconds\n");sleep(5);// 使用 usleep() 函数暂停程序执行 1000000 微秒(即 1 秒)printf("Sleep program for 1000000 microseconds (1 second)\n");usleep(1000000);// 程序结束printf("Program finished\n");return 0;
}
代码解释
  1. sleep() 函数

    • sleep(5):使当前线程暂停 5 秒,然后继续执行后续代码。
    • 作用:在执行某些任务之前强制等待一定的时间,这对需要做定时延迟的操作非常有用。
  2. usleep() 函数

    • usleep(1000000):使当前线程暂停 1,000,000 微秒,即 1 秒。
    • 作用:提供比 sleep() 更高精度的延迟功能,可以精确到微秒级别。
    • 需要注意的是,usleep() 精度较高,但具体暂停时间可能会受到系统的活动和计时器粒度的影响,因此有可能比设定的时间稍长。
  3. 输出

    Sleep program for 5 seconds
    Sleep program for 1000000 microseconds (1 second)
    Program finished
    

    • 程序首先等待 5 秒,然后输出第二行信息,再等待 1 秒,最后输出结束信息。
usleep()sleep()nanosleep() 的区别
  1. sleep(seconds)

    • 暂停线程指定的秒数。
    • 适用场合:适合需要较长时间延迟(例如秒级别)的场合。
  2. usleep(useconds_t usec)

    • 暂停线程指定的微秒数。
    • 适用场合:适合需要比 sleep() 更精细的延迟控制,比如毫秒级的等待。
  3. nanosleep()

    • 允许用户以纳秒精度指定休眠时间,适合需要更高精度的时间控制。
    • 它的函数声明是:
      int nanosleep(const struct timespec *req, struct timespec *rem);
      

    • 参数
      • req:指定需要暂停的时间,包含秒和纳秒。
      • rem:如果休眠被中断,则返回剩余的休眠时间。

usleep() 的使用场景

  1. 多线程中的延迟

    • 在多线程编程中,线程之间可能需要一些延迟来防止资源竞争,usleep() 可以让线程在执行任务之间休眠一些时间,从而降低 CPU 占用并减少资源争用。
  2. 游戏循环和动画

    • 在简单的游戏开发中,可以使用 usleep() 来控制帧率,确保每一帧之间有一个固定的时间间隔,从而实现平滑的动画效果。
  3. 定时任务

    • 在编写定时任务时,可以使用 usleep()sleep() 来定时地执行某些操作,例如每隔 1 秒采集一次传感器数据。

代码应用场景

  • 在很多应用场合中,线程之间的任务执行需要有一个节奏,不是所有的任务都需要立即连续地执行。例如,在对某个传感器进行定时读取时,可能每隔 500 毫秒读取一次数据,使用 usleep(500000) 就可以方便地实现这样的功能。

  • 在多线程应用中,usleep() 可以用来暂时暂停当前线程的执行,以便其他线程有机会运行。例如,一个线程在等待某些资源可用时可以通过 usleep() 暂时休眠,以避免反复轮询导致 CPU 资源的浪费。

注意事项

  1. 精度限制

    • 尽管 usleep() 提供微秒级的控制,但具体的延迟时间可能会因系统负载等原因而稍长。对于需要非常精确的计时任务,可能需要更复杂的同步机制。
  2. 系统调用影响

    • 在一些系统中,调用 usleep() 可能会受到系统定时器的粒度影响。如果需要非常精确的延迟控制,建议使用 nanosleep()

nanosleep() 示例

以下是一个使用 nanosleep() 的简单示例,用于精确控制线程暂停的时间。

#include <stdio.h>
#include <time.h>int main() {struct timespec ts;ts.tv_sec = 0;          // 秒数部分ts.tv_nsec = 500000000; // 纳秒部分(0.5 秒)printf("Sleeping for 0.5 seconds...\n");nanosleep(&ts, NULL);printf("Wake up after 0.5 seconds\n");return 0;
}

总结

  • sleep()usleep()nanosleep() 都是用于暂停线程执行的函数,适用于不同精度的时间控制。
  • usleep() 提供微秒级的延迟控制,在多线程和定时任务中非常有用。
  • nanosleep() 提供纳秒级的控制,适合需要高精度延迟的任务。
  • 这些函数在需要控制任务执行节奏、避免资源争用或实现实时响应时非常有用。

 

相关文章:

[OS] 终端控制(Terminal Control) 暂停执行线程(Suspend Executing Thread)

7. 终端控制&#xff08;Terminal Control&#xff09; 在终端中打印信息时&#xff0c;我们可以使用 ANSI 转义序列来控制光标的位置、清除屏幕等操作。\033 是转义字符&#xff0c;用于引导 ANSI 控制码来控制终端显示。可以将它理解为“命令前缀”&#xff0c;后面跟着具体…...

水陆两栖车应对应急事件发挥的作用_鼎跃安全

随着气候变化&#xff0c;城市内涝等问题日益严重。为了应对可能出现的洪水灾害&#xff0c;许多城市开始将水陆两栖车纳入应急救援装备体系。在暴雨引发城市积水时&#xff0c;水陆两栖车可以作为一种高效的救援和运输工具&#xff0c;及时疏散被困群众&#xff0c;运送应急物…...

CI/CD 流水线系统-开源框架Tekton

文章目录 CI/CD 流水线系统-开源框架Tekton什么是TektonTekton优点Tekton 组件介绍Tekton 概念术语 CI/CD 流水线系统-开源框架Tekton 什么是Tekton 官网&#xff1a;https://tekton.dev/ Tekton 是一个强大、灵活的构建 CI/CD 流水线系统的开源框架,允许开发者构建、测试和…...

Spring MVC(下)

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多JavaEE知识 目录 1.响应 1.1 返回静态页面 1.2 返回数据ResponseBody 1.3 返回HTML代码⽚段 1.4 返回JSON 1.5 设置状态码 1.6 设置Header 2 . …...

开发涉及的安全规范整理

#1024程序员节&#xff5c;征文# 文章目录 前言安全场景与措施API调用方式鉴权参数校验日志打印数据保存加密 总结 前言 这篇文章我们来整理下写代码和方案设计中的安全规范问题&#xff0c;内容偏服务端&#xff0c;即使是入门的新人&#xff0c;如果你对安全有所了解会让成熟…...

驱动开发系列26 - Linux Graphics 调试 mesa 的 glDrawArrays (二)

目录 一:概述 二:Gallium3D 的工作流程 三:tc_draw_vbo 与 tc_call_draw_single 的关系: 四:tc_draw_vbo 与 tc_call_draw_single 的具体执行流程: 五:mesa中线程池设计介绍: 六:总结: 一:概述 众所周知,Mesa 的 Gallium3D 是一个图形驱动框架,它将图形管线…...

laya-spine动画的使用

laya2和laya3的spine动画在使用过程中并无太大区别&#xff0c;这里以laya3为例。 转换 首先将做好的spine动画按jison格式导出&#xff0c;导出完之后的文件应包括图集、图片和json类型的3个文件。然后再用laya的骨骼动画转换工具转换成laya内置的模式&#xff0c;转换后的文…...

Vue项目实战-新能源汽车可视化(一)(持续更新中)

一.项目代码 1.App.vue <template><!-- 模板--><div id"wrapper"><div style"width: 100%"><el-tabs v-model"activeName" id"tabs"> <!-- 标签栏里包含了三个标签面板&#xff0c;分别是研发与维…...

百度SEO前10关键词排名波动跟用户行为反馈有很大关系

大家好&#xff0c;我是林汉文&#xff08;谷歌SEO专家&#xff09;&#xff0c;在百度SEO优化中&#xff0c;网站的排名并非一成不变&#xff0c;尤其是前10名的位置&#xff0c;更是动态变化。很多站长可能会发现&#xff0c;有时明明内容质量不错&#xff0c;外链也稳定&…...

基于微信小程序的电影交流平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

Java实现 itext PDF文件打印水印(文字和图片水印)

itext PDF文件打印水印 前言&#xff1a;公司有个需求&#xff0c;打印的合同模板要加上水印&#xff0c;但是由于itext版本问题&#xff0c;网上千篇一律的方法基本都没办法有效使用&#xff0c;然后自己琢磨下&#xff0c;记录下实现水印的功能的笔记。多页上都加上水印&…...

面经之一:Synchronized与ReentrantLock区别

Synchronized与ReentrantLock是Java中用于实现线程同步的两种主要机制&#xff0c;它们各有特点和适用场景。以下是它们的主要区别&#xff1a; 实现方式&#xff1a; Synchronized&#xff1a;是Java语言内置的关键字&#xff0c;通过JVM层面的监视器&#xff08;Monitor&…...

论文速读:面向单阶段跨域检测的域自适应YOLO(ACML2021)

原文标题&#xff1a;Domain Adaptive YOLO for One-Stage Cross-Domain Detection 中文标题&#xff1a;面向单阶段跨域检测的域自适应YOLO 1、Abstract 域转移是目标检测器在实际应用中推广的主要挑战。两级检测器的域自适应新兴技术有助于解决这个问题。然而&#xff0c;两…...

React中在map遍历中,给虚拟标签(<></>)加key

有时我们可能会需要在遍历时使用虚拟标签包裹内容&#xff0c;而不使用实际标签 &#xff0c;这种时候会有一个问题&#xff0c;就是虚拟标签无法加key&#xff0c;这样控制台会一直有警告。 {[1,2,3,4].map(v><><div></div><div></div><…...

大数据生态守护:Hadoop的深度保护策略

PART 1 从Hadoop运行原理透视数据保护需求 1、Hadoop的定义与范畴 Hadoop&#xff0c;狭义而言&#xff0c;是一个专为大数据设计的分布式存储与计算平台&#xff0c;其核心组件包括HDFS&#xff08;Hadoop分布式文件系统&#xff09;、MapReduce&#xff08;分布式计算框架&a…...

代码欣赏之:此题易错在 a+b 非要写成 a-fabs(b).因为这样就成了浮点值了,得不到准确数

代码欣赏之&#xff1a;此题易错在 ab 非要写成 a-fabs(b).因为这样就成了浮点值了&#xff0c;得不到准确数 7-23 小孩子才做选择&#xff0c;大人全都要 #include<stdio.h> #include<math.h> int main() {int a,b;scanf("%d %d",&a,&b);if(a&…...

ECharts饼图-环形图,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个饼图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供详…...

arcgis js 怎么加载geoserver发布的wms服务

arcgis js api加载wms服务&#xff0c;官方的参考样例&#xff1a; WMSLayer | Sample Code | ArcGIS Maps SDK for JavaScript 4.30 | Esri Developer 按照官方样例加载比较奇怪&#xff0c;我们平常习惯用url或者json的方式加载&#xff0c;稍微改一下就行&#xff0c;如下…...

前端_006_Vue2

文章目录 vue常用属性生命周期模版语法自定义组件全局注册 单文件组件路由 本文全部参考Vue2 简介&#xff1a;Vue是一个数据响应式&#xff0c;MVVM模型的JS框架 官网&#xff1a;https://v2.cn.vuejs.org/v2/guide/ API&#xff1a;https://v2.cn.vuejs.org/v2/api/#method…...

论多端数据互通网游的架构评估

摘要 在2023年&#xff0c;笔者参与了一款多端数据互通网络游戏的架构评估工作&#xff0c;并担任评估团队的核心成员。该游戏支持PC、移动设备和游戏机等多种终端&#xff0c;实现了数据的实时互通。本文通过该项目的评估实践&#xff0c;探讨了多端数据互通网游架构评估的关…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...

Python的__call__ 方法

在 Python 中&#xff0c;__call__ 是一个特殊的魔术方法&#xff08;magic method&#xff09;&#xff0c;它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时&#xff08;例如 obj()&#xff09;&#xff0c;Python 会自动调用该对象的 __call__ 方法…...

若依项目部署--传统架构--未完待续

若依项目介绍 项目源码获取 #Git工具下载 dnf -y install git #若依项目获取 git clone https://gitee.com/y_project/RuoYi-Vue.git项目背景 随着企业信息化需求的增加&#xff0c;传统开发模式存在效率低&#xff0c;重复劳动多等问题。若依项目通过整合主流技术框架&…...