forked from daattali/beautiful-jekyll
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
47b7037
commit 378fa34
Showing
1 changed file
with
91 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# map如何知道自己被抢占 | ||
map的底层实现是hmap结构体,有一个叫flags的uint8类型字段。 | ||
|
||
下面这些常量表示flag每一个位的作用 | ||
```go | ||
// flags | ||
iterator = 1 // there may be an iterator using buckets | ||
oldIterator = 2 // there may be an iterator using oldbuckets | ||
hashWriting = 4 // a goroutine is writing to the map | ||
sameSizeGrow = 8 // the current map growth is to a new map of the same size | ||
``` | ||
|
||
其中这里关于如何判断锁冲突的是hashWriting字段 | ||
## 写 | ||
|
||
```go | ||
// 因为h.flags默认为0,所以hashWriting初始化应该为0,如果不为0说明其他goroutine在写 | ||
if h.flags&hashWriting != 0 { | ||
fatal("concurrent map writes") | ||
} | ||
// 开始写,writing位置为1 | ||
h.flags ^= hashWriting | ||
// 写之后判断,因为刚刚已经把writting置位1了,这里不应该为0,如果为0说明在写的过程中有人改过了。 | ||
if h.flags&hashWriting == 0 { | ||
fatal("concurrent map writes") | ||
} | ||
// 恢复原状 | ||
h.flags &^= hashWriting | ||
``` | ||
|
||
|
||
## 删除 | ||
```go | ||
// 判断是否为0,如果不为0则fatal | ||
if h.flags&hashWriting != 0 { | ||
fatal("concurrent map writes") | ||
} | ||
|
||
// 开始删除,置为1 | ||
h.flags ^= hashWriting | ||
|
||
// 如果等于0表示又其他go routine把它置为1了,fatal | ||
if h.flags&hashWriting == 0 { | ||
fatal("concurrent map writes") | ||
} | ||
// 恢复原状 | ||
h.flags &^= hashWriting | ||
``` | ||
|
||
## 读 | ||
```go | ||
// 读的时候只需要判断,不需要修改。 | ||
if h.flags&hashWriting != 0 { | ||
fatal("concurrent map read and map write") | ||
} | ||
## 番外篇 &^ 运算 | ||
暂时找不到更多概念,只能写个demo看看。 | ||
|
||
```go | ||
package main | ||
import "fmt" | ||
func test(testCases [][]int) { | ||
for _, testCase := range testCases { | ||
ret := testCase[0] &^ testCase[1] | ||
fmt.Printf("%v &^ %v = %v\n", testCase[0], testCase[1], ret) | ||
} | ||
} | ||
func main() { | ||
testcase := [][]int{ | ||
{0, 0}, | ||
{0, 1}, | ||
{1, 0}, | ||
{1, 1}, | ||
} | ||
test(testcase) | ||
} | ||
``` | ||
|
||
结果 | ||
``` | ||
0 &^ 0 = 0 | ||
0 &^ 1 = 0 | ||
1 &^ 0 = 1 | ||
1 &^ 1 = 0 | ||
|
||
``` |