unix环境高级编程 第一章 UNIX基础知识 Go实现代码

ls命令的Go语言实现

package main

import (
	"fmt"
	"os"
)

func main() {
	if len(os.Args) != 2 {
		panic("参数数量不足")
	}
	targetPath := os.Args[1]
	if dirList, err := os.ReadDir(targetPath); err == nil {
		for _, dirInfo := range dirList {
			fmt.Println(dirInfo.Name())
		}
	} else {
		fmt.Println(err.Error())
	}
}

从标准输入复制到标准输出

package main

import (
	"bufio"
	"os"
	"time"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	message, _ := reader.ReadString('\n')
	os.Stdout.WriteString(message)

	time.Sleep(time.Second)
}

打印进程的pid

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Printf("hello world from process ID %d\n", os.Getpid())
}

使用fork创建子进程并查看运行结果

package main

import (
	"fmt"
	"os"
	"os/exec"
	"syscall"
)

func main() {
	bar := 2
	foo := "demo"

	id, _, _ := syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)
	if id == 0 {
		bar++
		cmd := exec.Command("ls")
		out, _ := cmd.CombinedOutput()
		fmt.Printf("ls output: %s\n", string(out))
		fmt.Printf("in child: %d, bar: %v, foo: %v\n", os.Getpid(), bar, foo)
	} else {
		foo += "hello"
		fmt.Printf("in parent: %d, bar: %v, foo: %v\n", os.Getpid(), bar, foo)
	}
}

获取uid与gid

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Printf("uid = %d, gid = %d\n", os.Getuid(), os.Getgid())
}

信号signal

中断键 interrupt key, 通常是delete键或者ctrl+c和退出键ctrl+.他们用于中断当前进程.另一种产生信号的方式是调用名为kill的函数.

package main

import (
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	bar := 2
	foo := "demo"

	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT)

	go func() {
		for sig := range c {
			switch sig {
			case syscall.SIGINT:
				fmt.Printf("interrupt no: %d\n", syscall.SIGINT)
				os.Exit(-1)
			}
		}
	}()

	time.Sleep(5 * time.Second)
	id, _, _ := syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)
	if id == 0 {
		bar++
		cmd := exec.Command("ls")
		out, _ := cmd.CombinedOutput()
		fmt.Printf("ls output: %s\n", string(out))
		fmt.Printf("in child: %d, bar: %v, foo: %v\n", os.Getpid(), bar, foo)
	} else {
		foo += "hello"
		fmt.Printf("in parent: %d, bar: %v, foo: %v\n", os.Getpid(), bar, foo)
	}
}

UNIX时间值

UNIX中有两种时间

  1. 日历时间, 从1970年1月1日00:00:00所经过的秒数累计值.这些时间可用于记录文件最近一次的修改时间等.
  2. 进程时间.也成为CPU时间, 用以度量进程使用的cpu资源.进程时间以tick记录.

当度量一个进程的执行时间时, UNIX系统使用三个进程时间值:

  • 时钟时间
  • 用户CPU时间
  • 系统CPU时间

时钟时间又称为墙上时间(wall clock time). 它是进程运行的时间总量, 其值与系统中同时运行的进程数有关. 在我们报告时钟时间时, 都是在系统中没有其他活动时进行度量的.
用户时间是执行用户指令所用的时间量.
系统cpu时间是为该进程执行内核所经历的时间.
例如,只有一个进程执行一个系统服务, 如read或write, 则在内核内执行该服务所花费的时间就计入该进程的系统cpu时间.
用户cpu时间与系统cpu时间的和常被称为CPU时间.
要得到一个程序运行的时钟时间, 用户时间和系统时间很容易, 使用time(1)命令即可.

$ cd /usr/include
$ time grep _POSIX_SOURCE */*.h > /dev/null
real 0m19.81s
user 0m0.43s 
sys 0m4.53s

time函数的输出格式与所使用的shell有关系.

系统调用和库函数

系统调用和库函数之间有重大区别, 但从用户角度看, 其区别并不非常重要.
本书的系统调用和库函数都是以c函数的形式存在.
但我们应当理解, 如果希望的话, 我们可以替换库函数, 但是通常不能替换系统调用.
以内存分配函数malloc为例, 有很多方法可以进行内存管理.如果不喜欢这样的操作方法, 可以定义自己的malloc函数, 它可能将使用sbrk系统调用.
事实上,有很多软件包, 她们实现自己的存储器分配算法, 但仍然使用sbrk系统调用.
下图显示了应用程序, malloc函数和sbrk系统调用的关系
在这里插入图片描述
从图中可见, 两者职责不同,相互分开, 内核中的系统调用分配另外一块空间给进程, 而库函数malloc则管理这一空间.

另外一个可说明系统调用和库函数区别的例子是, UNIX提供决定当前时间和日期的接口.某些操作系统提供一个系统调用以返回时间, 而另一个则返回日期.
任何特殊的处理, 例如正常时制与夏令时的转换, 由内核处理或要求人为干预.
UNIX则不同, 它只提供一个系统调用, 该系统调用返回国际标准时间1970年1月1日0点以来所经过的秒数.对该值的任何解释, 如将其变换为人们可读的, 使用本地时区的时间和日期, 都留给用户进程进行. 在标准c库中, 提供了若干函数来处理大多数情况. 这些库函数处理各种细节, 例如各种夏令时算法.
应用程序可以调用系统调用或库函数, 而很多库函数则会调用系统调用.
系统调用与库函数的另一个差别是: 系统调用通常提供了一种最小接口, 而库函数通常提供比较复杂的功能. 我们从sbrk系统调用和malloc库函数之间的差别中可以看到这一点.
以后比较不带缓冲的IO函数(第三章)与标准IO函数(第五章)时, 还将看到这种差别.
进程控制系统调用(fork,exec和wait)通常由用户的应用程序直接调用. 但为了简化某些常见情况, UNIX系统也提供了一些库函数, 如system和popen.在这里插入图片描述
为了使读者了解大多数程序员应用的unix系统接口, 我们不得不既说明系统调用, 还要介绍某些库函数.
例如若只说明sbrk系统调用, 那么就会忽略很多应用程序使用的malloc库函数.

小结

本节快速浏览了UNIX, 说明了某些以后会多次用到的基本术语.
下一节是关于UNIX标准化的内容, 以及这方面的工作对当前系统的影响.标准, 特别是ANSI C标准和POSIX.1标准将影响本书的余下部分.

课后问题

日历时间存放在有符号32位整型中, 什么时候会溢出(2038年溢出)
如果进程时间存在32位整型数中, 每秒100tick, 经过多少天溢出(248天)

package main

import "fmt"

func main() {
	var n int32
	n = 2147483646
	for i := 0; i < 5; i++ {
		fmt.Println("n:", n)
		n += 1
	}
}

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

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

相关文章

淡季不淡,满帮一季度净利创历史新高的背后原因是什么?

进入五月&#xff0c;经济复苏的成果越发体现在很多基础行业的表现中。经济的“大动脉”货运行业&#xff0c;也迎来一份新答卷。 北京时间5月22日美股盘前&#xff0c;数字货运平台满帮集团&#xff08;NYSE:YMM&#xff0c;简称&#xff1a;满帮&#xff09;&#xff0c;发布…

自动化测试用例怎么写?最全自动化测试用例设计编写指南...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

python---变量(3)

求字符串的长度 使用len来求字符串中有几个字符 字符串的拼接 此时是把a2字符串拼接到a1字符串的末尾&#xff0c;得到更大的字符串&#xff0c;对于原来的a1和a2是没有影响的&#xff01; 不能把字符串和数字混合相加&#xff01; 这个时候程序就会报错&#xff0c;不能…

GO语言并发编程入门:Goroutine、Channel、Context、并发安全、GMP调度模型

GO语言并发编程入门&#xff1a;Goroutine、Channel、Context、并发安全、GMP调度模型 1.GO并发介绍 并发&#xff1a;多线程程序在一个核的cpu上运行。 并行&#xff1a;多线程程序在多个核的cpu上运行。 由上可知并发不是并行&#xff0c;并行是直接利用多核实现多线程的运…

【分布式文件存储】MinIO部署及实现文件上传下载

目录 概述 MinIO集群部署 准备docker-compose.yml 测试启动 MinIO用户管理 Buckets管理 创建Buckets MinIO客户端 引入依赖 文件上传下载Demo 调用API碰到的问题 概述 MinIO | 高性能, Kubernetes 原生对象存储 MinIO是全球领先的对象存储先锋&#xff0c;目前在全世…

照相机标定

一.相机标定的原理 1.1 相机如何成像&#xff1a; 相机成像系统中&#xff0c;共包含四个坐标系&#xff1a;世界坐标系、相机坐标系、图像坐标系、像素坐标系。 1.1.1 世界坐标系&#xff1a; 世界坐标系&#xff08;world coordinate&#xff09;&#xff0c;也称为测量坐…

Cobalt Strike工具基本使用

Cobalt Strike 安装启动启动server端启动client目标机器连接 工具基使用用户驱动攻击屏幕截图进程列表键盘记录文件管理远程vnc远程代理端口扫描 生成后门被攻击者运行后门文件后查看结果 钓鱼攻击信息收集网站克隆文件下载 安装 网盘地址&#xff1a;链接&#xff1a;https:/…

PyG的Planetoid无法直接下载Cora等数据集的解决方法

问题描述&#xff1a; 在使用PyG的时候&#xff0c;通常会涉及到一些公共数据集的下载&#xff0c;由于网络问题&#xff0c;导致无法下载出现以下问题&#xff1a; 尝试了很多的方法都没有成功&#xff08;主要是个人比较菜&#xff01;&#xff09;。但是皇天不负有心人&am…

文心一言和ChatGPT最全对比

文心一言和ChatGPT都是基于深度学习技术的自然语言处理模型&#xff0c;有各自的优势和使用场景&#xff0c;无法简单地比较 ChatGPT 和文心一言哪一个功能更强大&#xff0c;它们各自具有优势和局限性&#xff0c;需要根据具体需求进行选择&#xff0c;以下一些具体对比&#…

分布式网络通信框架(十)——Mprpc框架使用示例

发布一个服务提供远程调用方法的流程 若想要发布一个服务提供一些远程调用方法&#xff0c;步骤如下&#xff1a; 先在protobuf文件中添加参数和返回值的message 类型&#xff0c;然后再添加希望提供的服务 service 类型&#xff08;如UserServiceRpc&#xff09;和 其中的方…

C++内存管理和模板

文章目录 内存管理new和delete 函数模板隐式实例化显式实例化 类模板 内存管理 有时候我们需要动态的申请内存,比如队列,栈,二叉树等数据结构,我们一开始并不知道要存储多少个数据,也就是不确定究竟要多大的内存,给小了存不下,给大了会造成内存资源的浪费,因此动态的申请内存是…

原工程运行正常,重新复制一份后再 npm install 后再运行就报错的解决办法

原工程&#xff0c;运行正常 将刚刚的工程复制一份呢&#xff0c;重新 npm install 再 npm run serve 就报错 出现这个问题十之八九都是依赖的问题。有可能是因为这个工程里面之前安装过一些东西&#xff0c;后来莫名其妙的就把 package.json 里面相关的依赖给删掉了。但由于原…

【数据结构】顺序二叉树的实现—以堆的实现为例、堆的调整、堆的创建、堆的插入和删除、堆排序

文章目录 1.堆的概念及结构2.堆的实现&#xff08;以大堆为例&#xff09;2.1堆的插入2.1.1堆的向上调整算法 2.2堆的删除2.2.1堆的向下调整算法 2.3堆的创建2.4有关建堆的时间复杂度 3.堆排序4.C语言堆实现源码 1.堆的概念及结构 堆就是顺序结构二叉树。 如果有一个关键码的集…

jetcache参考文档

jetcache简介 https://github.com/alibaba/jetcache/blob/master/docs/CN/GettingStarted.md 简介 JetCache是一个基于Java的缓存系统封装&#xff0c;提供统一的API和注解来简化缓存的使用。 JetCache提供了比SpringCache更加强大的注解&#xff0c;可以原生的支持TTL、两级…

shell变量类型含义 长方形面积计算 截取相应字段方法

1.总结变量的类型及含义&#xff1f; 2.实现课堂案例计算长方形面积&#xff1f;&#xff08;6种方式&#xff09; 3.定义变量urlhttps://blog.csdn.net/weixin_45029822/article/details/103568815&#xff08;通过多种方法实现&#xff09; 1&#xff09;截取网站访问的协议 …

文心一言 VS 讯飞星火 VS chatgpt (22)-- 算法导论4.2 2题

二、为Strassen算法编写伪代码。 文心一言&#xff1a; Strassen算法是一种用于矩阵乘法的算法&#xff0c;它的核心思想是通过不断将原始矩阵分割成较小的子矩阵来实现高效的乘法运算。以下是Strassen算法的伪代码&#xff1a; function Strassen(A, B): if A[0][0] 0 or…

Springboot整合WebSocket

目录 1.WebSocket 简介 2.WebSocket 实战 1.WebSocket 简介 WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要…

基于html+css的图展示98

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

C++入门

文章目录 &#x1f600;1. 命名空间&#x1f604;1.1 命名空间定义&#x1f604;1.2 命名空间使用 &#x1f60a;2. 输入和输出&#x1f609;3. 缺省参数&#x1fae0;3.1 缺省参数概念&#x1fae0;3.2 缺省参数分类 &#x1f62c;4. 函数重载&#x1f644;4.1 函数重载概念&a…

TypeScript9-声明文件

本篇文章来讲 TypeScript 的声明文件。 当我们在使用第三方库的时候&#xff0c;很多第三方库不是用 TS 写的&#xff0c;它们是通过原生的 JavaScript 或者是浏览器 / 或者是 node 提供的 run time 对象。如果我们直接使用 TS 肯定就会报编译不通过。 1. 声明语句 假设一个…