2021-05-05 22:27:48    10    0    0
有时候,我们使用go语言开发一些程序的时候,往往出现多个进程同时操作同一份文件的情况,这很容易导致文件中的数据混乱。 我们需要采用一些手段来平衡这些冲突:需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock。 对于flock,我们最常见的例子就是nginx,进程起来后就会把当前的PID写入这个文件,当然如果这个文件已经存在了,也就是前一个进程还没有退出,那么Ngi
2021-05-05 22:23:20    3    0    0
前言 题目是golang下文件锁的使用,但本文的目的其实是通过golang下的文件锁的使用方法,来一窥文件锁背后的机制。 为什么需要文件锁 > 只有多线程/多进程这种并发场景下读写文件,才需要加锁 - 场景1-读写并发 读写并发场景下,如果不加锁,就会出现读到脏数据的情况。想象一下,读文件的进程,读到第500字节,有其它进程以覆盖写的方式向文件中写入1000字节,那读进程读到的后500字
2021-05-04 12:09:08    10    0    0
UUID 全称是 Universally Unique Identifier,也就是说,每个分区有一个唯一的 UUID 值,Linux系统(红帽系列的Fedora,Cent OS,或Debian系列的Ubuntu,LinuxMint,等等)都采用UUID方式挂载分区,避免发生分区识别混乱的问题。 `fstab`文件位于`/etc/`下,挂在分区的格式为: ``` # `
2021-05-03 21:48:18    7    0    0
1. 插上硬盘查看状态,可以看到/dev/sda1就是需要挂载的移动硬盘。 ``` sudo fdisk -l ``` ![](/api/file/getImage?fileId=608fff1d04aa04416a001648) 2. 查看硬盘状态,此时还没有挂载上去。 ``` df -h ``` ![](/api/file/getImage?file
2021-05-01 22:54:24    7    0    0
## 0x00 前言 最开始了解到 yubikey 是因为和一个朋友聊到 PGP 的问题,我觉得 PGP 保存私钥很麻烦,换一个环境或者电脑被搬走的话还是存在一些风险的,放云上就更加不用说了。然后他就说你可以考虑一下 yubikey。 其实我之前也听某个群里的大佬说到过 yubikey,初听时就觉得这个东西应该很不错,安全级别应该很高,因为那会还没有开始使用 PGP,只是把 yubikey
ubuntu    2021-04-29 12:45:18    13    0    0
## 查看openssl的版本 ``` openssl version OpenSSL 1.1.1f 31 Mar 2020 ``` ## 下载 到官网下载合适的openssl版本 https://www.openssl.org/source/ ``` wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz tar -zxf o
2021-04-29 12:38:47    14    0    0
## GPGTools ### 安装GPGTools Mac用户在GPGTools官网下载,这是一款GUI的GPG管理软件,也会自动装上`gpg-agent`无需另行下载 ### Yubikey 1. 安装Yubikey管理软件 ``` $ brew install yubikey-personalization ``` 2. 插入Yubikey 3. 设置Yubikey为`
docker portainer    2021-04-28 20:18:05    21    0    0
# docker更新portainer-ce2.0 前两天,我在使用portainer的过程中发现左下角提醒有新版本的portainer需要安装,google了一圈如何升级portainer,并没有找到我需要的资料,就算获取了portainer:last也无效 后面查看了新版portainer的文章,发现images的名字是portainer-ce,好家伙,新版直接把镜像名字也改了。 #
2021-04-28 18:34:26    7    0    0
# Raspberry ## 安装 全程未使用显示器,但使用了一个直连网线. 0. 前往[官网](https://www.raspberrypi.org/downloads/raspbian/)下载镜像 * 使用种子文件下载才是最新版 * 下载完成后务必确认文件完整 `sha1sum *-raspbian-jessie.zip` 0. 烧录启动盘 ```bash unzip *-ra
2021-04-28 15:23:03    11    0    0
下面这个demo,在32位系统(我测试的运行环境:32位arm linux)会崩溃。 ``` package main import ( "sync/atomic" ) type Foo struct { a int64 b int32 c int64 } func main() { var f Foo atomic.AddInt64(&f.a, 1) // 这里不会崩溃 atomic.AddInt64(&f.c, 1) // 这里会崩溃 } ``` 崩溃信息如下: ``` panic: unaligned 64-bit atomic operation goroutine 1 [running]: runtime/internal/atomic.panicUnaligned() /usr/local/go/src/runtime/internal/atomic/unaligned.go:8 +0x24 runtime/internal/atomic.Xadd64(0x1416084, 0x1, 0x0, 0x75fd8, 0x14000e0) /usr/local/go/src/runtime/internal/atomic/asm_arm.s:233 +0x14 main.main() /tmp/test.go:16 +0x3c ``` 在Go源码go/src/sync/atomic/doc.go的注释中,有如下描述: ``` // BUG(rsc): On x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX. // // On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core. // // On ARM, x86-32, and 32-bit MIPS, // it is the caller's responsibility to arrange for 64-bit // alignment of 64-bit words accessed atomically. The first word in a // variable or in an allocated struct, array, or slice can be relied upon to be // 64-bit aligned. ``` 大致意思是,在一些32位的环境(包括x86和arm),标准库sync/atomic中操作int64的函数存在bug,调用者需自行保证,被操作的int64是按64位对齐的。。否则给你来个panic。惊不惊喜意不意外。。 这里简单说一下64位对齐是啥意思,拿上面那个demo来说: ``` type Foo struct { a int64 // 位置从0开始,满足64位对齐 b int32 c int64 // 位置`size(a)+sizeof(b)=96`,不是64的倍数,就不满足了 } ``` 所以,atomic.AddInt64(&f.a, 1)不会崩溃,atomic.AddInt64(&f.c, 1)会崩溃。 值得一提的有几点: 64位系统原子操作int64没这个问题 32位系统原子操作int32也没问题 32位系统原子操作int64有问题,注意,是原子操作有问题,并不是说int64不能用 uint64和int64是一样,也即这个问题只关心整型位数,不关心符号 以上说的原子操作,特指Go标准库sync/atomic中的函数 解决方法有两种: 1. 一种是保证结构体中的需要使用atomic的int64按64位对齐,比如最简单的就是把这些变量的声明写在结构体的最前面。同时,还需要保证这种结构体被其他结构体嵌套时,也要64位对齐。缺点是编写和维护代码的心智负担比较大。 2. 另一种就是把int64变量的原子操作改成mutex互斥锁保护。缺点是mutex比atomic的开销大。
1/6