summaryrefslogtreecommitdiffstats
path: root/code/projects/godo.html
diff options
context:
space:
mode:
Diffstat (limited to 'code/projects/godo.html')
-rw-r--r--code/projects/godo.html26
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 &lt;stdio.h&gt; 35 <pre><code class="language-c">#include &lt;stdio.h&gt;
35#include &lt;sys/syscall.h&gt; 36#include &lt;sys/syscall.h&gt;
36#include &lt;sys/types.h&gt; 37#include &lt;sys/types.h&gt;
37#include &lt;sys/wait.h&gt; 38#include &lt;sys/wait.h&gt;
@@ -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 &lt;unistd.h&gt; 107#include &lt;unistd.h&gt;
107#include &lt;stdio.h&gt; 108#include &lt;stdio.h&gt;
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 &lt;stdio.h&gt; 135#include &lt;stdio.h&gt;
135#include &lt;pthread.h&gt; 136#include &lt;pthread.h&gt;
136#include &lt;sys/syscall.h&gt; 137#include &lt;sys/syscall.h&gt;
@@ -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
164write(1, &quot;main: thread 139903502108416\n&quot;, 29) = 29 165write(1, &quot;main: thread 139903502108416\n&quot;, 29) = 29
165clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f3dd308e9d0) = 21757 166clone(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
177pid_t 178pid_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>