diff options
Diffstat (limited to 'code/projects/godo.html')
-rw-r--r-- | code/projects/godo.html | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/code/projects/godo.html b/code/projects/godo.html index ed64840..c967797 100644 --- a/code/projects/godo.html +++ b/code/projects/godo.html | |||
@@ -6,15 +6,16 @@ | |||
6 | <meta name="generator" content="pandoc" /> | 6 | <meta name="generator" content="pandoc" /> |
7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> |
8 | <title>godo知识总结</title> | 8 | <title>godo知识总结</title> |
9 | <link rel="stylesheet" href="https://test.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> | 9 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> |
10 | <script type="text/javascript" src="https://test.qin-juan-ge-zhu.top/common/js/myhighlight.js"></script> | 10 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> |
11 | <script type="text/javascript" src="https://test.qin-juan-ge-zhu.top/common/script4code.js"></script> | ||
12 | </head> | 11 | </head> |
13 | 12 | ||
14 | <body> | 13 | <body> |
15 | <div class="pandoc"> | 14 | <div class="pandoc"> |
16 | <div class="main"> | 15 | <div class="main"> |
17 | <p class="title">godo知识总结</p> | 16 | <header id="title-block-header"> |
17 | <p class="title">godo知识总结</p> | ||
18 | </header> | ||
18 | <h1 id="背景说明">背景说明</h1> | 19 | <h1 id="背景说明">背景说明</h1> |
19 | <p>本文档对<a href="https://git.qin-juan-ge-zhu.top/godo">godo</a>编写过程中新了解到的技术、遇到的问题进行简要说明,以备所需。</p> | 20 | <p>本文档对<a href="https://git.qin-juan-ge-zhu.top/godo">godo</a>编写过程中新了解到的技术、遇到的问题进行简要说明,以备所需。</p> |
20 | <h1 id="系统调用">系统调用</h1> | 21 | <h1 id="系统调用">系统调用</h1> |
@@ -31,7 +32,7 @@ | |||
31 | <li>在 C 语言中直接调用同名函数,但大概率经过了 glibc 的封装</li> | 32 | <li>在 C 语言中直接调用同名函数,但大概率经过了 glibc 的封装</li> |
32 | <li>手动封装。如下:</li> | 33 | <li>手动封装。如下:</li> |
33 | </ul> | 34 | </ul> |
34 | <pre><code>#include <stdio.h> | 35 | <pre><code class="language-c">#include <stdio.h> |
35 | #include <sys/syscall.h> | 36 | #include <sys/syscall.h> |
36 | #include <sys/types.h> | 37 | #include <sys/types.h> |
37 | #include <sys/wait.h> | 38 | #include <sys/wait.h> |
@@ -50,7 +51,7 @@ int main(){ | |||
50 | return 0; | 51 | return 0; |
51 | }</code></pre> | 52 | }</code></pre> |
52 | <p>这种封装方式与经常被用来当作 os 教材的 Linux-0.11/0.12 有所区别。Linux-0.11 环境上,unistd.h 大致如下:</p> | 53 | <p>这种封装方式与经常被用来当作 os 教材的 Linux-0.11/0.12 有所区别。Linux-0.11 环境上,unistd.h 大致如下:</p> |
53 | <pre><code>#ifndef _UNISTD_H | 54 | <pre><code class="language-c">#ifndef _UNISTD_H |
54 | #define _UNISTD_H | 55 | #define _UNISTD_H |
55 | 56 | ||
56 | ... | 57 | ... |
@@ -102,7 +103,7 @@ return -1; \ | |||
102 | 103 | ||
103 | #endif</code></pre> | 104 | #endif</code></pre> |
104 | <p>可以看到,Linux-0.11 上,封装的一般方法为:</p> | 105 | <p>可以看到,Linux-0.11 上,封装的一般方法为:</p> |
105 | <pre><code>#define __LIBRARY__ // 一定要在unistd.h之前 | 106 | <pre><code class="language-c">#define __LIBRARY__ // 一定要在unistd.h之前 |
106 | #include <unistd.h> | 107 | #include <unistd.h> |
107 | #include <stdio.h> | 108 | #include <stdio.h> |
108 | 109 | ||
@@ -124,13 +125,13 @@ int main() { | |||
124 | tasks 表里的一个 task,而每个 task 才具有独一无二的 id</strong>。</p> | 125 | tasks 表里的一个 task,而每个 task 才具有独一无二的 id</strong>。</p> |
125 | <h3 id="常见系统调用的分析">常见系统调用的分析</h3> | 126 | <h3 id="常见系统调用的分析">常见系统调用的分析</h3> |
126 | <p>看看这个:</p> | 127 | <p>看看这个:</p> |
127 | <pre><code>extern int pthread_create (pthread_t *__restrict __newthread, | 128 | <pre><code class="language-c">extern int pthread_create (pthread_t *__restrict __newthread, |
128 | const pthread_attr_t *__restrict __attr, | 129 | const pthread_attr_t *__restrict __attr, |
129 | void *(*__start_routine) (void *), | 130 | void *(*__start_routine) (void *), |
130 | void *__restrict __arg) __THROWNL __nonnull ((1, 3));</code></pre> | 131 | void *__restrict __arg) __THROWNL __nonnull ((1, 3));</code></pre> |
131 | <p><code>pthread_create</code>函数的第一个参数,就是一个 pthread_t 类型的指针,处理后将 task 的 id 写到指针指向的区域。</p> | 132 | <p><code>pthread_create</code>函数的第一个参数,就是一个 pthread_t 类型的指针,处理后将 task 的 id 写到指针指向的区域。</p> |
132 | <p>让我们来看一段简单的代码:</p> | 133 | <p>让我们来看一段简单的代码:</p> |
133 | <pre><code>// test.c | 134 | <pre><code class="language-c">// test.c |
134 | #include <stdio.h> | 135 | #include <stdio.h> |
135 | #include <pthread.h> | 136 | #include <pthread.h> |
136 | #include <sys/syscall.h> | 137 | #include <sys/syscall.h> |
@@ -160,7 +161,7 @@ int main() { | |||
160 | return 0; | 161 | return 0; |
161 | }</code></pre> | 162 | }</code></pre> |
162 | <p>当我们使用<code>strace ./test</code>来查看上述代码时,会发现情况如下:</p> | 163 | <p>当我们使用<code>strace ./test</code>来查看上述代码时,会发现情况如下:</p> |
163 | <pre><code>clone(child_stack=0x7f3dd28bbff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f3dd28bc9d0, tls=0x7f3dd28bc700, child_tidptr=0x7f3dd28bc9d0) = 21756 | 164 | <pre><code class="language-c">clone(child_stack=0x7f3dd28bbff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f3dd28bc9d0, tls=0x7f3dd28bc700, child_tidptr=0x7f3dd28bc9d0) = 21756 |
164 | write(1, "main: thread 139903502108416\n", 29) = 29 | 165 | write(1, "main: thread 139903502108416\n", 29) = 29 |
165 | clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f3dd308e9d0) = 21757 | 166 | clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f3dd308e9d0) = 21757 |
166 | --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21757, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- | 167 | --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21757, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- |
@@ -173,7 +174,7 @@ exit_group(0) = ? | |||
173 | <p>从这样的输出里,我们可以清晰地看到,<strong>无论是<code>pthread_create</code>还是<code>fork</code>(指库函数),本质上都是封装了<code>clone</code>系统调用,即使 | 174 | <p>从这样的输出里,我们可以清晰地看到,<strong>无论是<code>pthread_create</code>还是<code>fork</code>(指库函数),本质上都是封装了<code>clone</code>系统调用,即使 |
174 | Linux 本身提供了专门的 fork 系统调用。</strong>也许这是 glibc 和 Linux 都想在添加功能的基础上保证代码兼容性?花开两朵各表一枝了属于是。</p> | 175 | Linux 本身提供了专门的 fork 系统调用。</strong>也许这是 glibc 和 Linux 都想在添加功能的基础上保证代码兼容性?花开两朵各表一枝了属于是。</p> |
175 | <p>这一结论也可以从 glibc 的代码中得到验证:</p> | 176 | <p>这一结论也可以从 glibc 的代码中得到验证:</p> |
176 | <pre><code>// 文件 glibc-2.18/nptl/sysdeps/unix/sysv/linux/pt-fork.c | 177 | <pre><code class="language-c">// 文件 glibc-2.18/nptl/sysdeps/unix/sysv/linux/pt-fork.c |
177 | pid_t | 178 | pid_t |
178 | __fork (void) | 179 | __fork (void) |
179 | { | 180 | { |
@@ -354,7 +355,8 @@ PSEUDO_END (syscall)</code></pre> | |||
354 | <li>gcc 技术大全</li> | 355 | <li>gcc 技术大全</li> |
355 | <li>黑客调试技术大全</li> | 356 | <li>黑客调试技术大全</li> |
356 | </ul> | 357 | </ul> |
357 | <script src="https://test.qin-juan-ge-zhu.top/common/js/comment.js"></script> | 358 | <p class="time">2024.8</p> |
359 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> | ||
358 | </div> | 360 | </div> |
359 | </div> | 361 | </div> |
360 | </body> | 362 | </body> |