Skip to content

Commit

Permalink
线程(部分)
Browse files Browse the repository at this point in the history
  • Loading branch information
polaris1119 committed Sep 3, 2016
1 parent 0418ec3 commit 8004315
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 9 deletions.
59 changes: 51 additions & 8 deletions chapter10/10.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

每个进程都有一些属性,`os` 包提供了一些函数可以获取进程属性。

## 进程 ID

每个进程都会有一个进程ID,可以通过 `os.Getpid` 获得。同时,每个进程都有创建自己的父进程,通过 `os.Getppid` 获得。

## 进程凭证

Unix 中进程都有一套数字表示的用户 ID(UID) 和组 ID(GID),有时也将这些 ID 称之为进程凭证。Windows 下总是 -1。
Expand Down Expand Up @@ -97,6 +101,45 @@ func main() {

此外,`os` 还提供了获取辅助组 ID 的函数:`os.Getgroups()`

### 操作系统用户

`os/user` 允许通过名称或 ID 查询用户账号。用户结构定义如下:

```
type User struct {
Uid string // user id
Gid string // primary group id
Username string
Name string
HomeDir string
}
```
`User` 代表一个用户帐户。

在 POSIX 系统中 Uid 和 Gid 字段分别包含代表 uid 和 gid 的十进制数字。在 Windows 系统中 Uid 和 Gid 包含字符串格式的安全标识符(SID)。在 Plan 9 系统中,Uid、Gid、Username 和 Name 字段是 /dev/user 的内容。

`Current` 函数可以获取当前用户账号。而 `Lookup``LookupId` 则分别根据用户名和用户 ID 查询用户。如果对应的用户不存在,则返回 `user.UnknownUserError ``user.UnknownUserIdError`

```
package main
import (
"fmt"
"os/user"
)
func main() {
fmt.Println(user.Current())
fmt.Println(user.Lookup("xuxinhua"))
fmt.Println(user.LookupId("0"))
}
// Output:
// &{502 502 xuxinhua /home/xuxinhua} <nil>
// &{502 502 xuxinhua /home/xuxinhua} <nil>
// &{0 0 root root /root} <nil>
```

## 进程的当前工作目录

一个进程的当前工作目录(current working directory)定义了该进程解析相对路径名的起点。新进程的当前工作目录继承自其父进程。
Expand Down Expand Up @@ -161,13 +204,13 @@ import (
func main() {
fmt.Println("The num of environ:", len(os.Environ()))
gctrace, ok := os.LookupEnv("gctrace")
godebug, ok := os.LookupEnv("GODEBUG")
if ok {
fmt.Println("gctrace==", gctrace)
fmt.Println("GODEBUG==", godebug)
} else {
fmt.Println("gctrace not exists!")
os.Setenv("gctrace", "2")
fmt.Println("after setenv:", os.Getenv("gctrace"))
fmt.Println("GODEBUG not exists!")
os.Setenv("GODEBUG", "gctrace=1")
fmt.Println("after setenv:", os.Getenv("GODEBUG"))
}
os.Clearenv()
Expand All @@ -176,14 +219,14 @@ func main() {
// Output:
// The num of environ: 25
// gctrace not exists!
// after setenv: 2
// GODEBUG not exists!
// after setenv: gctrace=1
// clearenv, the num: 0
```

另外,`ExpandEnv``Getenv` 功能类似,不过,前者使用变量方式,如:

os.ExpandEnv("$gctrace") 和 os.Getenv("gctrace") 是一样的。
os.ExpandEnv("$GODEBUG") 和 os.Getenv("GODEBUG") 是一样的。

实际上,`os.ExpandEnv` 调用的是 `os.Expand(s, os.Getenv)`

Expand Down
28 changes: 28 additions & 0 deletions chapter10/10.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 10.3 线程 #

与进程类似,线程是允许应用程序并发执行多个任务的一种机制。一个进程可以包含多个线程。同一个程序中的所有线程均会独立执行相同程序,且共享同一份全局内存区域。

同一进程中的多个线程可以并发执行。在多处理器环境下,多个线程可以同时并行。如果一个线程因等待 I/O 操作而遭阻塞,那么其他线程依然可以继续运行。

在 Linux 中,通过系统调用 `clone()` 来实现线程的。从前面的介绍,我们知道,该系统调用也可以用来创建进程。实际上,从内核的角度来说,它并没有线程这个概念。Linux 把所有的线程都当作进程来实现。内核并没有准备特别的调度算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个使用某些共享资源的进程。所以,在内核中,它看起来就是一个普通的进程(只是该进程和其他一些进程共享某些资源,如地址空间)。

在 Go 中,通过 `clone()` 系统调用来创建线程,其中的 `clone_flags` 为:

```
cloneFlags = _CLONE_VM | /* share memory */
_CLONE_FS | /* share cwd, etc */
_CLONE_FILES | /* share fd table */
_CLONE_SIGHAND | /* share sig handler table */
_CLONE_THREAD /* revisit - okay for now */
```

也就是说,父子俩共享了地址空间(_CLONE_VM)、文件系统资源(_CLONE_FS)、文件描述符(_CLONE_FILES)和信号处理程序(_CLONE_SIGHAND)。而 `_CLONE_THREAD` 则会将父子进程放入相同的线程组。这样一来,新建的进程和父进程都叫做线程。




# 导航 #

- 上一节:[进程属性和控制](10.2.md)
- 下一节:[进程间通信](10.4.md)

9 changes: 9 additions & 0 deletions chapter10/10.4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# 10.3 进程间通信 #

进程之间用来相互通讯和同步

# 导航 #

- 上一节:[创建进程](10.1.md)
- 下一节:[进程间通信](10.3.md)

3 changes: 2 additions & 1 deletion preface.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
* 第十章 [进程、线程与 goroutine](chapter10/10.0.md)
- 10.1 [创建进程](chapter10/10.1.md)
- 10.2 [进程属性和控制](chapter10/10.2.md)
- 10.3 [进程间通信](chapter10/10.3.md)
- 10.3 [线程](chapter10/10.3.md)
- 10.4 [进程间通信](chapter10/10.4.md)
* 第十一章 网络通信与互联网 (Internet)
* 第十二章 email
* 第十三章 应用构建、debug 与测试
Expand Down

0 comments on commit 8004315

Please sign in to comment.