> For the complete documentation index, see [llms.txt](https://xd96dx.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://xd96dx.gitbook.io/docs/you-xi-kai-fa/skynet-cong-demo-dao-yuan-ma/skynet-yuan-ma-fen-xi-qi-dong-liu-cheng-zhi-xian-cheng-chi-qi-dong.md).

# skynet 源码分析-启动流程之线程池启动

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FLuHp0hVbFcM78UwuKgho%2Fimage.png?alt=media&amp;token=ea2463be-2405-4f64-826c-0f1721923248" alt=""><figcaption></figcaption></figure>

在上一节启动了 skynet 的服务之后, 这些service 就要开始工作了, 主要是启动了工作线程, 启动的过程比较简单, 所以主要讲这些线程是如何工作的

## start()

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FlHbGeWsoW7uqiW2Wl3BJ%2Fimage.png?alt=media&amp;token=c12f59e1-c3a9-487b-8b21-4358248c06ac" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2Fp2Pvm9WurOicFNi102jk%2Fimage.png?alt=media&amp;token=b1c21409-faf3-43ab-84d1-0b7cdeeb2632" alt=""><figcaption></figcaption></figure>

thread 就是配置文件中 thread参数, 工作线程数

pid\[thread+3] 这里的 3 是为了下面启动monitor, timer, 和socket 用的, 前半部分就是初始化 mutex, cond

### thread\_mointor

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FhfqttDeKhWvjiKsROTPN%2Fimage.png?alt=media&amp;token=67750e23-0cd5-4126-880a-4e65021bd061" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FUETPOUOgJUKmlrAMpM85%2Fimage.png?alt=media&amp;token=b840991f-a03e-44d7-b181-40feeae05893" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FZ1ISf12MYepYofTpUjqi%2Fimage.png?alt=media&amp;token=8ac3eada-5399-4752-86fe-3d3f380f643d" alt=""><figcaption><p>monitor</p></figcaption></figure>

* count: 工作线程数
* m: 存储与每个线程的监控信息
* cond: 工作线程会等待这个 cond 知道被唤醒
* mutex: 锁
* sleep: 空闲线程数
* quit: 是否退出标志位

这里的 monitor\_check 是skynet 检查死循环的机制, 每次进入时 check\_version 被赋值, 如果下一次check\_version 和 version 相同, 就说明两个服务之间可能一直在往来发送这个消息没有处理, 就会把这个 handle对应的context 释放, 结束死循环

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FifvlYAP84K7G3UEHXyq9%2Fimage.png?alt=media&amp;token=62cfdf29-9c75-48d7-b786-0bf2ae050fcb" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FzUVNtBAxcFT7u5n4aFfk%2Fimage.png?alt=media&amp;token=81ff213e-7bac-47cd-bf3a-797b3c56bb50" alt=""><figcaption></figcaption></figure>

skynet\_monitor\_trigger 就是操作version 的地方, 在每次执行线程操作的时候会对这个原子量+1

### thread\_timer

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FhfC4cW9KKc7fVifeY1ND%2Fimage.png?alt=media&amp;token=8aaa9c27-1134-4e6f-857a-fee667af6e4a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FKdLYDdKEknvbU5kzGeYD%2Fimage.png?alt=media&amp;token=278035cd-8aa5-44c5-b233-e44e3c007d18" alt=""><figcaption></figcaption></figure>

timer 比较容易, 就是不停的在更新全局timer 和 socket\_server 的时间戳, 定时任务就是靠这个更新的时间戳工作, 136行的wakeup 就是来唤醒线程的

### thread\_socket

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FTJm6Fkj0fzdMWoT1rVd1%2Fimage.png?alt=media&amp;token=60c95317-cfb3-4eb4-8f91-4a47089346f9" alt=""><figcaption></figcaption></figure>

这里监听的全局 socket(之前创建的pipe), 当有事件发生时, wakeup唤醒线程, 这里的 skynet\_socket\_poll 方法是 epoll 在监听 pipe, 之后skynet 的网络通信部分会讲到

### thread\_worker

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2FF3dcSmHYlo78lNQZQ5xD%2Fimage.png?alt=media&amp;token=9085020c-5b5c-45a7-b3a3-8d30703ec3bd" alt=""><figcaption><p>worker_parm</p></figcaption></figure>

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2Fwlj1e9PsccaAjyAMGuYT%2Fimage.png?alt=media&amp;token=7028ac1b-5944-4080-b068-7fdd73141ad5" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1038370733-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsZbVV9N3S0zSZ23753et%2Fuploads%2F5WvK73VKNgJeLI77QjYO%2Fimage.png?alt=media&amp;token=b38ce658-4d9d-4101-86cd-e253ef09a34a" alt=""><figcaption><p>thread_worker</p></figcaption></figure>

thread\_worker 在启动前, 绑定了全局的 monitor, 分配了每个线程的权重 weight, 用来配置每个线程的占用, 这里thread\_worker 主要逻辑是: 不断地从全局的 message\_queue中取任务并执行 (skynet\_context\_message\_dispatch), 当空闲时 wait 在条件变量 cond 处, 往复执行,具体任务是如何添加和取出并执行会在skynet 任务调度处详细讲解
