Go语言中调用time.Now()时有没有发生系统调用?

在探究“Go语言中调用time.Now()时有没有发生系统调用?”这个问题之前,我们先复习下什么是系统调用。

什么是系统调用?

系统调用(system call)指的是运行在用户空间的程序向操作系统内核请求具有更高权限的服务。究竟是哪些服务呢?这些服务指的是由操作系统内核进行管理的服务,比如进程管理,存储,内存,网络等。以打开文件为例子,用户程序需要调用openread这两个系统调用,在c语言中要么使用libc库实现(底层也是系统调用),要么直接使用系统调用实现。

Linux系统中为什么一定要经过系统调用才能访问特资源呢,难道就不能在用户空间完成调用访问功能吗?之所以这么设计是考虑到系统隔离性,提高系统安全性和容错性,避免恶意攻击。操作系统把CPU访问资源的安全级别分为4个级别,这些级别称为特权级别(privilege level),也称为CPU环(CPU Rings)。在任一时刻,CPU都是在一个特定的特权级下运行的,从而决定了什么可以做,什么不可以做。这些级别可以形象的考虑成一个个圆环,里面是最高特权的Ring0,向外依次是Ring1,Ring2,最后是最低特权的Ring3。当发生系统调用时候,应用程序将会从应用空间进入内核空间,此时特权级别会由Ring3提升到Ring0,应用程序代码也会跳到相关系统调用代码处执行。

Read More

Golang源码分析系列之atomic底层实现

atomic概述

atomic是Go内置原子操作包。下面是官方说明:

Package atomic provides low-level atomic memory primitives useful for implementing synchronization algorithms. atomic包提供了用于实现同步机制的底层原子内存原语。

These functions require great care to be used correctly. Except for special, low-level applications, synchronization is better done with channels or the facilities of the sync package. Share memory by communicating; don’t communicate by sharing memory. 使用这些功能需要非常小心。除了特殊的底层应用程序外,最好使用通道或sync包来进行同步。通过通信来共享内存;不要通过共享内存来通信

Read More

这可能是你最想要的一份GDB使用指南

GDB简介

GDB(GNU symbolic Debugger)是Linux系统下的强大的调试工具,可以用来调试ada, c, c++, asm, minimal, d, fortran, objective-c, go, java,pascal 等多种语言。

我们以调试go代码为示例来介绍GDB的使用。源码内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import "fmt"

func add(a, b int) int {
sum := 0
sum = a + b
return sum
}
func main() {
sum := add(10, 20)
fmt.Println(sum)
}

Read More

Golang源码分析系列之sync.Map底层实现

Golang中sync/map提供了并发读写map功能。这里面分析的源码基于go1.14.13版本。

sync.Map的结构

1
2
3
4
5
6
7
8
9
10
11
type Map struct {
mu Mutex // 排他锁,用于对dirty map操作时候加锁处理

read atomic.Value // read map

// dirty map。新增key时候,只写入dirty map中,需要使用mu
dirty map[interface{}]*entry

// 用来记录从read map中读取key时miss的次数
misses int
}

Read More

Protocol buffers语法

简介

Protocol Buffers简称Protobuf,是google公司推出的一种数据描述语言。Protocol buffers具有平台无关、语言无关、二进制格式编码、编码后体积小,序列化和反序列化快、类型安全、向后兼容等特点。

Protocol buffers有专门的语法结构来定义数据结构。消息和RPC服务接口是Protocol buffers中两大基本组成。消息类似一个Json object,RPC服务接口定义了服务所具有的接口和所依赖的消息类型。

Protocol buffers定义的数据结构应该保存在.proto后缀名的文件中。目前最新版本的语法协议是proto3。

Read More

Golang反射三定律

原文地址:https://blog.golang.org/laws-of-reflection

简介

Reflection(反射)在计算机中表示程序能够检查自身结构的能力,尤其是类型。它是元编程的一种形式,也是最容易让人迷惑的一部分。

类型和接口

因为反射建立在类型系统之上,所以我们从类型的基础知识说起。Go是静态类型语言。每个变量都有一个静态类型,也就是在编译时已经确定了。比如int, float32, *MyType, []byte等。我们进行如下声明:

1
2
3
4
type MyInt int

var i int
var j MyInt

Read More

Go语言实现简易版netstat命令

netstat工作原理

netstat命令是linux系统中查看网络情况的一个命令。比如我们可以通过netstat -ntlp | grep 8080查看监听8080端口的进程。

netstat工作原理如下:

  1. 通过读取/proc/net/tcp 、/proc/net/tcp6文件,获取socket本地地址,本地端口,远程地址,远程端口,状态,inode等信息
  2. 接着扫描所有/proc/[pid]/fd目录下的的socket文件描述符,建立inode到进程pid映射
  3. 根据pid读取/proc/[pid]/cmdline文件,获取进程命令和启动参数
  4. 根据2,3步骤,即可以获得1中对应socket的相关进程信息

Read More