<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>C on Momori Nakano</title><link>https://momori.dev/tags/c/</link><description>Recent content in C on Momori Nakano</description><generator>Hugo -- 0.147.0</generator><language>en-us</language><lastBuildDate>Fri, 24 Feb 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://momori.dev/tags/c/index.xml" rel="self" type="application/rss+xml"/><item><title>Apache Bench でベンチマークできるミニマルな C 言語製 HTTP サーバ</title><link>https://momori.dev/posts/c-server-for-apache-bench/</link><pubDate>Fri, 24 Feb 2023 00:00:00 +0000</pubDate><guid>https://momori.dev/posts/c-server-for-apache-bench/</guid><description>&lt;p>&lt;code>ab&lt;/code> コマンド, つまり &lt;a href="https://httpd.apache.org/docs/2.4/programs/ab.html">Apache HTTP server benchmarking tool&lt;/a> をつかってベンチマークできる状態の HTTP サーバを C 言語で作る. なるべくシンプルに必要最小限の要素のみを持ったコードを目指す.&lt;/p>
&lt;p>手堅いエンジニアは高速化のために, いきなりコードを書いたりしない. 計測できる環境を整えておかないと, 高速化をしてもその効果を測ることができない.&lt;br>
このサーバを出発点として手を加えて (例えばマルチスレッド化したり IO 多重化をしたりして) サーバのパフォーマンスがどのように変化するかを確かめるために使うことを想定している. ソースコード全体は &lt;a href="https://github.com/momori256/cs2">https://github.com/momori256/cs2&lt;/a> にある.&lt;/p>
&lt;h2 id="ソケット">ソケット&lt;/h2>
&lt;p>&lt;code>ab&lt;/code> を使うには HTTP を解すサーバでなければならないため, まずは TCP での通信を実装する.&lt;br>
ソケットプログラミングはお決まりのコードなので説明は省く. いつもお決まりを忘れてしまうので, &lt;code>man getaddrinfo&lt;/code> の EXAMPLE をいつも参照している.&lt;/p>
&lt;p>&lt;code>socket&lt;/code>, &lt;code>bind&lt;/code>, &lt;code>listen&lt;/code> をして &lt;code>accept&lt;/code> できるソケットを作成する部分は以下の関数だ.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 1
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 2
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 3
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 4
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 5
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 6
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 7
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 8
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7"> 9
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">10
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">11
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">12
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">13
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">14
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">15
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">16
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">17
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">18
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">19
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">20
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">21
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">22
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">23
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">24
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">25
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">26
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">27
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">28
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">29
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">30
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">31
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">32
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">33
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">34
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">35
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">36
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">37
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">38
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">39
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">40
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">41
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">42
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">43
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">44
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">45
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">46
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">47
&lt;/span>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">48
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">int&lt;/span> &lt;span style="color:#8caaee">sock_create&lt;/span>(&lt;span style="color:#ca9ee6">const&lt;/span> &lt;span style="color:#e78284">char&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">*&lt;/span> &lt;span style="color:#ca9ee6">const&lt;/span> port, &lt;span style="color:#e78284">int&lt;/span> backlog) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">typedef&lt;/span> &lt;span style="color:#ca9ee6">struct&lt;/span> addrinfo addrinfo;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> addrinfo hints &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> {&lt;span style="color:#ef9f76">0&lt;/span>};
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> hints.ai_family &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> AF_INET; &lt;span style="color:#737994;font-style:italic">// IPv4.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">&lt;/span> hints.ai_socktype &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> SOCK_STREAM; &lt;span style="color:#737994;font-style:italic">// TCP.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">&lt;/span> hints.ai_flags &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> AI_PASSIVE; &lt;span style="color:#737994;font-style:italic">// Server.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> addrinfo&lt;span style="color:#99d1db;font-weight:bold">*&lt;/span> head;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">const&lt;/span> &lt;span style="color:#e78284">int&lt;/span> result &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> &lt;span style="color:#8caaee">getaddrinfo&lt;/span>(&lt;span style="color:#99d1db">NULL&lt;/span>, port, &lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&lt;/span>hints, &lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&lt;/span>head);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">if&lt;/span> (result) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8caaee">fprintf&lt;/span>(stderr, &lt;span style="color:#a6d189">&amp;#34;getaddrinfo. err[%s]&lt;/span>&lt;span style="color:#8caaee">\n&lt;/span>&lt;span style="color:#a6d189">&amp;#34;&lt;/span>, &lt;span style="color:#8caaee">gai_strerror&lt;/span>(result));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8caaee">exit&lt;/span>(&lt;span style="color:#ef9f76">1&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e78284">int&lt;/span> sfd &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> &lt;span style="color:#ef9f76">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">for&lt;/span> (addrinfo&lt;span style="color:#99d1db;font-weight:bold">*&lt;/span> p &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> head; p &lt;span style="color:#99d1db;font-weight:bold">!=&lt;/span> &lt;span style="color:#99d1db">NULL&lt;/span>; p &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> p&lt;span style="color:#99d1db;font-weight:bold">-&amp;gt;&lt;/span>ai_next) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sfd &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> &lt;span style="color:#8caaee">socket&lt;/span>(p&lt;span style="color:#99d1db;font-weight:bold">-&amp;gt;&lt;/span>ai_family, p&lt;span style="color:#99d1db;font-weight:bold">-&amp;gt;&lt;/span>ai_socktype, p&lt;span style="color:#99d1db;font-weight:bold">-&amp;gt;&lt;/span>ai_protocol);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">if&lt;/span> (sfd &lt;span style="color:#99d1db;font-weight:bold">==&lt;/span> &lt;span style="color:#99d1db;font-weight:bold">-&lt;/span>&lt;span style="color:#ef9f76">1&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e78284">int&lt;/span> val &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> &lt;span style="color:#ef9f76">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">if&lt;/span> (&lt;span style="color:#8caaee">setsockopt&lt;/span>(sfd, SOL_SOCKET, SO_REUSEADDR, &lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&lt;/span>val, &lt;span style="color:#ca9ee6">sizeof&lt;/span>(val)) &lt;span style="color:#99d1db;font-weight:bold">==&lt;/span> &lt;span style="color:#99d1db;font-weight:bold">-&lt;/span>&lt;span style="color:#ef9f76">1&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8caaee">error&lt;/span>(&lt;span style="color:#a6d189">&amp;#34;setsockopt&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">if&lt;/span> (&lt;span style="color:#8caaee">bind&lt;/span>(sfd, p&lt;span style="color:#99d1db;font-weight:bold">-&amp;gt;&lt;/span>ai_addr, p&lt;span style="color:#99d1db;font-weight:bold">-&amp;gt;&lt;/span>ai_addrlen) &lt;span style="color:#99d1db;font-weight:bold">==&lt;/span> &lt;span style="color:#99d1db;font-weight:bold">-&lt;/span>&lt;span style="color:#ef9f76">1&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8caaee">close&lt;/span>(sfd);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">break&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8caaee">freeaddrinfo&lt;/span>(head);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">if&lt;/span> (&lt;span style="color:#99d1db;font-weight:bold">!&lt;/span>sfd) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8caaee">error&lt;/span>(&lt;span style="color:#a6d189">&amp;#34;socket, bind&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">if&lt;/span> (&lt;span style="color:#8caaee">listen&lt;/span>(sfd, backlog) &lt;span style="color:#99d1db;font-weight:bold">==&lt;/span> &lt;span style="color:#99d1db;font-weight:bold">-&lt;/span>&lt;span style="color:#ef9f76">1&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8caaee">error&lt;/span>(&lt;span style="color:#a6d189">&amp;#34;listen&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">return&lt;/span> sfd;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="http-リクエストとレスポンス">HTTP リクエストとレスポンス&lt;/h2>
&lt;p>&lt;code>accept&lt;/code> して &lt;code>read&lt;/code> すればメッセージを受信できる. 動作の確認には &lt;code>telnet&lt;/code> のようなプリミティブなツールが役に立つ.&lt;/p></description></item><item><title>『Linux と pthreads による マルチスレッドプログラミング入門』で pthreads を実践する</title><link>https://momori.dev/posts/linux-pthreads/</link><pubDate>Tue, 22 Nov 2022 00:00:00 +0000</pubDate><guid>https://momori.dev/posts/linux-pthreads/</guid><description>&lt;p>&lt;a href="https://www.shuwasystem.co.jp/book/9784798053721.html">Linux と pthreads による マルチスレッドプログラミング入門&lt;/a> は pthreads の入門書です.
基礎から説明してあるので Linux でのマルチスレッドプログラミングを学びたい方におすすめです.&lt;/p>
&lt;p>pthreads は知っていましたし, ミューテックスなどのマルチスレッドプログラミングの概念もある程度知っていたのですが, 改めて pthreads で実践してみようと思いました.&lt;/p>
&lt;h2 id="必要なもの一通り">必要なもの一通り&lt;/h2>
&lt;p>スレッドの生成と破棄, ミューテックス, 条件変数など, 必要なものは一通り説明されている.&lt;br>
多数ある pthreads の関数から特に重要なものがピックアップされており, 説明も深入りしすぎず手短なので気負わずにさくっと読める.&lt;/p>
&lt;p>もっと詳しく知りたい場合は man を参照すればよい. というか実際には主だった関数に限っても引数や返り値の意味を覚えられるわけではないので, 結局 man はいつも参照するから, 詳細が省かれていても手間は対して変わらない. 確かこういう関数があったかなぁとぼんやり覚えているくらいで十分だろう.&lt;br>
説明をコンパクトにまとめることも大事である.&lt;/p>
&lt;h2 id="スレッドプールを実装">スレッドプールを実装&lt;/h2>
&lt;p>本書の後半ではスレッドセーフなキューを実装する. そしてそのキューを使ってスレッドプールを備えた並行サーバを実装する.&lt;br>
ミューテックスと条件変数があれば実装はそれほど難しくないだろうと思っていたが, 実際に手を動かして試してみるのは大事だと思う. 事実, ロック絡みで少しハマったりした.&lt;br>
Linux の技術書ではソケット関連のサンプルが頻繁に登場するので随分見慣れた. ソケットのプログラムを書くたびに面倒さを感じつつお馴染みのコードを書いている.&lt;/p>
&lt;h2 id="動きのあるサンプル">動きのあるサンプル&lt;/h2>
&lt;p>CLI のプログラムだとどうしても絵的には退屈になりがちだが, 本書はエンタメ性を意識しているのか面白いサンプルが使われている. 端末上をハエが飛び回るのだ.&lt;/p>
&lt;p>&lt;img alt="demo" loading="lazy" src="https://github.com/momori256/momori.dev/assets/90558309/429e8eb3-e3bc-4ae1-b985-9c121a64f64a">&lt;/p>
&lt;p>ハエの数だけスレッドがあり, 並行にハエの位置が計算されている.&lt;br>
CLI でのグラフィカルなプログラムを作るために &lt;a href="https://invisible-island.net/ncurses/">ncurses&lt;/a> を使ったことがあったのだが, エスケープシーケンス (&lt;code>printf(&amp;quot;\033[2J&amp;quot;)&lt;/code> で画面クリアなど) でもこれくらいのものが簡単にできると知って感心した. 少し見た目にこだわりたいときはちょうどよいかもしれない.&lt;/p>
&lt;h2 id="結語">結語&lt;/h2>
&lt;p>マルチスレッドプログラミングは難しいと常々思っていますが, 基本的なライブラリを使うのはそれほど難しくありません. できる限りロジックをシンプルにするのが重要だと感じました.&lt;/p>
&lt;p>コンパクトな本書に倣って記事もコンパクトにしてみました. 本の紹介や学んだことのまとめをするのに毎回長い文章を書く必要はありませんし, 必要最小限はプログラマの美学ですし (ですよね？), たまにはこれくらい短い記事でも良いと思いました.&lt;/p></description></item><item><title>C のエレガンスが詰まった『The C Programming Language』</title><link>https://momori.dev/posts/the-c-programming-language/</link><pubDate>Sun, 06 Nov 2022 00:00:00 +0000</pubDate><guid>https://momori.dev/posts/the-c-programming-language/</guid><description>&lt;p>&lt;a href="https://s3-us-west-2.amazonaws.com/belllabs-microsite-dritchie/cbook/index.html">『The C Programming Language』&lt;/a> は C 言語の教科書です.&lt;/p>
&lt;p>最新の第二版が出版されたのが 1988 年ですから流石に時代を感じますが, C の原点を知る歴史読み物的な価値があります.&lt;br>
個人的に, 配列やポインタ絡みの異常に複雑な型や &lt;code>typedef&lt;/code> などの文法に疑問や不満を持っていたのですが, 本書を読み一部が解消されました.&lt;/p>
&lt;h2 id="コンパクトな言語">コンパクトな言語&lt;/h2>
&lt;p>C 言語はコンパクトな言語である. 本書はサンプルプログラムを交えつつ C の文法を解説しているが, 付録を除けば約 160 ページしかない. それでいてプログラムを書くのに必要な機能は一通り揃っているから, 小さいことは良いことであるという UNIX 哲学を体現したような言語だと思う.&lt;/p>
&lt;p>本書でよく引き合いに出される Pascal や FORTRAN といった言語が当時は流行っていたのだろうが, 著者の一人である Kernighan は &lt;a href="http://www.lysator.liu.se/c/bwk-on-pascal.html">Why Pascal is Not My Favorite Programming Language&lt;/a> という論文を書いていたようだし, それらの改良版言語という意味もあるのかもしれない. 今となっては一般的となった概念も, C によってもたらされたものは多いのだろう.&lt;/p>
&lt;h2 id="複雑な型の読み方">複雑な型の読み方&lt;/h2>
&lt;p>配列やポインタ絡みでやたらと型の記述が複雑になるが, その読み方を整理しよう.&lt;/p>
&lt;h3 id="型を文に翻訳する方法">型を文に翻訳する方法&lt;/h3>
&lt;p>まずは簡単な型を見てみる.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">int&lt;/span> &lt;span style="color:#99d1db;font-weight:bold">*&lt;/span>x
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>x は int 型の値を指すポインタである.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code>&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#838ba7">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">int&lt;/span> &lt;span style="color:#99d1db;font-weight:bold">*&lt;/span>x[&lt;span style="color:#ef9f76">13&lt;/span>]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>x は int 型の値を指すポインタの配列 (サイズ 13) である.&lt;/p></description></item><item><title>『ふつうの Linux プログラミング』で 3 本の柱をものにする</title><link>https://momori.dev/posts/standard-linux-programming/</link><pubDate>Sun, 24 Jul 2022 00:00:00 +0000</pubDate><guid>https://momori.dev/posts/standard-linux-programming/</guid><description>&lt;h2 id="ふつうの-linux-プログラミングで-3-本の柱をものにする">『ふつうの Linux プログラミング』で 3 本の柱をものにする&lt;/h2>
&lt;p>&lt;a href="https://www.sbcr.jp/product/4797386479/">『ふつうの Linux プログラミング』&lt;/a> は Linux での C 言語プログラミング入門書です.&lt;br>
3 つのコンセプトを軸に据えた説明が特徴で, すんなり読めて自然に Linux の勘所が分かるような構成です.&lt;/p>
&lt;p>3 つのコンセプトとは&lt;/p>
&lt;ul>
&lt;li>ストリーム&lt;/li>
&lt;li>ファイルシステム&lt;/li>
&lt;li>プロセス&lt;/li>
&lt;/ul>
&lt;p>のことです. これらを中心に据えて Linux の仕組みを学びます.&lt;/p>
&lt;p>タイトルにある「ふつうの」は標準的な方法を学ぶという意図を表しています. Linux の中心的な仕組みを知ることができるだけでなく, &lt;code>cat&lt;/code> や &lt;code>grep&lt;/code> など身近なコマンドを実装するなどの実例も豊富なので, 「API は分かったけど結局どう使うのか分からない」といったことがありません. 実践しながら Linux の仕組みを学びたい方におすすめです.&lt;/p>
&lt;h2 id="3-つのコンセプト">3 つのコンセプト&lt;/h2>
&lt;p>まずは 3 つのコンセプトについての説明です.&lt;/p>
&lt;ul>
&lt;li>データを保存する場所である「ファイルシステム」&lt;/li>
&lt;li>コンピュータ上での活動の主体である「プロセス」&lt;/li>
&lt;li>プロセスがファイルや他のプロセスとデータをやり取りするための「ストリーム」&lt;/li>
&lt;/ul>
&lt;p>ストリームは本書独自の用語のようですが, バイト列の流れのことです.&lt;/p>
&lt;p>この 3 つのコンセプトが念頭にあれば Linux の様々なものを整理して理解することができます. 以下のような説明してみます.&lt;/p>
&lt;ul>
&lt;li>リダイレクト: プロセスの標準入出力ストリームの先をファイルに変える機能&lt;/li>
&lt;li>パイプ: プロセスとプロセスを繋ぐストリーム&lt;/li>
&lt;li>シグナル: カーネルからプロセスへのストリーム (のようなもの)&lt;/li>
&lt;li>パーミッション: プロセスからファイルへのアクセスを制限する仕組み&lt;/li>
&lt;/ul>
&lt;p>確かに Linux についての多くのものが整然と理解できる気がするので, この 3 つのコンセプトに着目して Linux を学ぶのは優れたアプローチだと思いました.&lt;/p></description></item></channel></rss>