---
# System prepended metadata

title: 'Program 2, multiThreading report'
tags: [courses, operating system]

---

# Program 2, multiThreading report

###### tags: `operating system`, `courses`

:::success
### mini-online-server
- Server
  - [x] Socket
  - [x] Thread
- Player
  - [x] set name
- GameRoom
  - [x] create
  - [x] join
  - [x] chat
  - [x] leave & delete
  - [ ] start game
- Game (not yet..)
  - [x] Rule design
  - [ ] ...
:::

## Environment

- OS
```shell=
❯ uname -a
Linux wasabineko-B550-AORUS-PRO-AC 5.8.0-50-generic #56~20.04.1-Ubuntu SMP Mon Apr 12 21:46:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
```
- Language
Python 3.8

- IDE
PyCharm Community

### source code
- [github](https://github.com/wasabi-neko/mini-online-server)

## Logic

### socket
socket 是一種對於連續網路封包溝通的工具，可使用 TCP 或 UDP 協定來傳輸資料

### Thread
主 thread 監聽目標 port 看有沒有新的連線，若有則建立一個新的 thread 負責服務此 socket 連線

```sequence
Client1 -> server: request for socket
server -> thread_pool: create thread1 for Client1
thread_pool -> Client1: thread1 accept socket
```

```graphviz
digraph {
  rankdir=LR;
  subgraph outside {
    client_1 [label="Client 1"];
    client_2 [label="Client 2"];
    s_1 [label="socket service" shape="box"];
    s_2 [label="socket service" shape="box"];
    {rank=same; client_1, client_2}
  }
  subgraph cluster_server {
    label="server";
    listen [label="listen port" shape="box"];
    process [label="main loop" shape="Mrecord"];
    t_1 [label="thread 1"];
    t_2 [label="thread 2"];
  }
  
  
  client_1->listen [label="request"]
  client_2->listen [label="request"]
  listen->process
  process->t_1->s_1
  process->t_2->s_2
}
```

### Chat Room Logic

Client 有 `Disconnected`, `Lobby`, `Room` 三種狀態
不同狀態的指定集和目標對象不同

```graphviz
digraph {
  label="Client status"
  rankdir=LR;
  Disconnect -> Lobby -> Room [dir="both"]
}
```

`Lobby console` 沒有實例(instance) 單純為 thread 內的資料操作
`RoomManager` 為 `singelton` 物件，負責管理所有的 `room`。
`Room` 實體，為 `shared memory`，可以被所有的 `thread` 請求，在修改資料時會使用 lock 以避免 race condition

```graphviz
digraph {
  node[shape="record"]
  subgraph cluster_thread {
    label="thread"
    c1 [label="<f0> client 1 |<f1> console|<f2> room_ptr|<f3> renderer"]
    if1 [label="switch" shape="diamond"]
    lobby [label="<f0> lobby console |{method |{<f1> create room|<f2> join room} }"]
  }
  rm [label="{<f0>Room manager|<f1> room list}"]
  r [label="<f0> room console|{method |{<f2> leave|<f1> say}}"]
  
  c1:f1 -> if1 [label="(command, self)"]
  c1:f2:w 
  
  if1 -> lobby:f0 [label="if status is lobby"]
  lobby:f1 -> rm [label="create room"]
  rm -> lobby:f2 [label="get room by name"]
  lobby:f2:e -> c1:f2 [label="assign"]
  
  if1 -> r:f0 [label="if status is room"]
  c2 [label="Client 2 | ...."]
  c3 [label="Client 3 | ...."]
  r:f1 -> c1:f3 [label="board cast"]
  r:f1 -> c2 [label="board cast"]
  r:f1 -> c3 [label="board cast"]
  r:f2 -> c1:f2 [label="delete"]
}
```

## References

- https://ithelp.ithome.com.tw/articles/10205819
- https://www.geeksforgeeks.org/socket-programming-python/
- https://www.geeksforgeeks.org/multithreading-python-set-1/
- https://www.geeksforgeeks.org/socket-programming-multi-threading-python/
- [really good artical](https://realpython.com/python-sockets/)
- [淺談IO](https://medium.com/@clu1022/%E6%B7%BA%E8%AB%87i-o-model-32da09c619e6)
