<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Глава 10 Каналы и select on Go: Under the Hood</title>
    <link>/ru/part3concurrency/ch10chan/</link>
    <description>Recent content in Глава 10 Каналы и select on Go: Under the Hood</description>
    <generator>Hugo</generator>
    <language>ru</language>
    <atom:link href="/ru/part3concurrency/ch10chan/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>10.1 Каналы и инженерия CSP</title>
      <link>/ru/part3concurrency/ch10chan/model/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>/ru/part3concurrency/ch10chan/model/</guid>
      <description>&lt;h1 id=&#34;101-каналы-и-инженерия-csp&#34;&gt;10.1 Каналы и инженерия CSP&lt;/h1&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;К этому разделу прилагается записанный доклад: &lt;a href=&#34;https://www.youtube.com/watch?v=d7fFCGGn0Wc&#34;&gt;онлайн на YouTube&lt;/a&gt;,&#xA;&lt;a href=&#34;https://changkun.de/s/chansrc/&#34;&gt;презентация в Google Slides&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;CSP даёт Go основание утверждать: процессы не разделяют состояние, а координируются исключительно через&#xA;передачу сообщений (&lt;a href=&#34;/ru/part1overview/ch01intro/csp/&#34;&gt;1.3&lt;/a&gt;). Настоящий раздел посвящён другому вопросу:&#xA;чтобы инженерный язык воплотил это утверждение на практике, какую форму должна принять «коммуникация», при&#xA;которой обычный программист мог бы использовать её корректно. Ответ Go — канал, элемент языка первого класса,&#xA;являющийся одновременно средством синхронизации и средством передачи данных. Мы начнём с изложения его модели&#xA;на поверхности языка: тип, синтаксис отправки и приёма, две семантики — буферизованная и небуферизованная,&#xA;ограничение направления и поведение nil — выстраивая интуицию, которая понадобится последующим разделам при&#xA;погружении в реализацию рантайма (&lt;a href=&#34;.././impl&#34;&gt;10.2&lt;/a&gt;–&lt;a href=&#34;.././pattern&#34;&gt;10.7&lt;/a&gt;).&lt;/p&gt;</description>
    </item>
    <item>
      <title>10.2 hchan: внутреннее устройство канала</title>
      <link>/ru/part3concurrency/ch10chan/impl/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>/ru/part3concurrency/ch10chan/impl/</guid>
      <description>&lt;h1 id=&#34;102-hchan-внутреннее-устройство-канала&#34;&gt;10.2 hchan: внутреннее устройство канала&lt;/h1&gt;&#xA;&lt;p&gt;&lt;a href=&#34;.././model&#34;&gt;10.1&lt;/a&gt; рассмотрел каналы в языке с позиции CSP: канал — это явный передаточный&#xA;механизм для сообщений, объединяющий «коммуникацию» и «синхронизацию» в единое целое. Данный&#xA;раздел разбирает его изнутри. В рантайме канал представлен структурой &lt;code&gt;hchan&lt;/code&gt;, весь секрет&#xA;которой сводится к единственной блокировке, кольцевому буферу и двум очередям ожидания.&#xA;Структура невелика, однако каждое поле существует по конкретной проектной причине. Стоит уяснить&#xA;эти немногие элементы — и вся последующая логика отправки, получения и select&#xA;(&lt;a href=&#34;.././sendrecv&#34;&gt;10.3&lt;/a&gt;–&lt;a href=&#34;.././lockfree&#34;&gt;10.6 Модель памяти и эволюция в сторону lock-free&lt;/a&gt;)&#xA;окажется лишь «перемещением данных, парковкой и пробуждением горутин поверх этой единственной&#xA;картины».&lt;/p&gt;</description>
    </item>
    <item>
      <title>10.3 Отправка, получение и прямая передача</title>
      <link>/ru/part3concurrency/ch10chan/sendrecv/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>/ru/part3concurrency/ch10chan/sendrecv/</guid>
      <description>&lt;h1 id=&#34;103-отправка-получение-и-прямая-передача&#34;&gt;10.3 Отправка, получение и прямая передача&lt;/h1&gt;&#xA;&lt;p&gt;&lt;a href=&#34;.././impl&#34;&gt;10.2&lt;/a&gt; очертил скелет &lt;code&gt;hchan&lt;/code&gt;: мьютекс, кольцевой буфер &lt;code&gt;buf&lt;/code&gt;, а также очередь&#xA;отправителей &lt;code&gt;sendq&lt;/code&gt; и очередь получателей &lt;code&gt;recvq&lt;/code&gt;. Настоящий раздел оживляет этот скелет и&#xA;отвечает на вопрос, что именно происходит внутри рантайма при одиночном &lt;code&gt;ch &amp;lt;- v&lt;/code&gt; и одиночном&#xA;&lt;code&gt;v := &amp;lt;-ch&lt;/code&gt;. Разобравшись в этом пути отправки/получения, оба наиболее часто задаваемых вопроса&#xA;о каналах — почему небуферизованный канал является единственной точкой рандеву и почему для&#xA;него получение происходит прежде, чем завершается соответствующая отправка&#xA;(&lt;a href=&#34;../../ch11sync/mem&#34;&gt;11.9&lt;/a&gt;), — сводятся к одному механизму: &lt;strong&gt;прямой отправке / прямому&#xA;получению&lt;/strong&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>10.4 Семантика закрытия канала</title>
      <link>/ru/part3concurrency/ch10chan/close/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>/ru/part3concurrency/ch10chan/close/</guid>
      <description>&lt;h1 id=&#34;104-семантика-закрытия-канала&#34;&gt;10.4 Семантика закрытия канала&lt;/h1&gt;&#xA;&lt;p&gt;В предыдущих разделах операции отправки и получения были «парными» рандеву: одна отправка соответствует одному получению, а избыточная сторона блокируется в ожидании. Закрытие — единственная операция над каналом с семантикой «один ко многим». &lt;code&gt;close(ch)&lt;/code&gt; вызывается одной горутиной, однако в тот же момент пробуждает всех получателей, заблокированных на канале, и заставляет немедленно запаниковать всех заблокированных отправителей. Эта возможность «однократного широковещания, пробуждающего всех» превращает закрытие из, казалось бы, малозначимой операции очистки в наиболее распространённый в Go механизм отмены и завершения работы. Паттерн done-канала и отмена через &lt;code&gt;context&lt;/code&gt; (&lt;a href=&#34;/ru/part3concurrency/ch11sync/context/&#34;&gt;11.8&lt;/a&gt;) восходят именно к этой семантике.&lt;/p&gt;</description>
    </item>
    <item>
      <title>10.5 Реализация select</title>
      <link>/ru/part3concurrency/ch10chan/select/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>/ru/part3concurrency/ch10chan/select/</guid>
      <description>&lt;h1 id=&#34;105-реализация-select&#34;&gt;10.5 Реализация select&lt;/h1&gt;&#xA;&lt;p&gt;Предыдущие разделы детально рассмотрели отправку и приём данных по одному каналу (&lt;a href=&#34;.././sendrecv&#34;&gt;10.3&lt;/a&gt;). На практике, однако, горутина редко наблюдает лишь один канал: требуется реагировать на &lt;strong&gt;первую готовую операцию&lt;/strong&gt; из нескольких отправок и приёмов и при этом &lt;strong&gt;избегать блокировки, если ни одна из них не готова&lt;/strong&gt;. &lt;code&gt;select&lt;/code&gt; создан именно для этого. Его семантика выглядит просто, однако реализация должна одновременно решить две нетривиальные задачи: как &lt;strong&gt;справедливо&lt;/strong&gt; выбрать ветку, когда несколько из них готовы, и как &lt;strong&gt;избежать взаимоблокировки&lt;/strong&gt; при захвате нескольких каналов в рамках одного select. Оба требования определяют всю структуру &lt;code&gt;selectgo&lt;/code&gt;, и данный раздел построен вокруг них.&lt;/p&gt;</description>
    </item>
    <item>
      <title>10.6 Модель памяти и эволюция без блокировок</title>
      <link>/ru/part3concurrency/ch10chan/lockfree/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>/ru/part3concurrency/ch10chan/lockfree/</guid>
      <description>&lt;h1 id=&#34;106-модель-памяти-и-эволюция-без-блокировок&#34;&gt;10.6 Модель памяти и эволюция без блокировок&lt;/h1&gt;&#xA;&lt;p&gt;Предыдущие разделы разобрали канал до составных частей: прямая передача в &lt;a href=&#34;.././sendrecv&#34;&gt;10.3&lt;/a&gt; позволяет&#xA;отправляющей и принимающей сторонам передавать значение напрямую, минуя кольцевой буфер, а &lt;code&gt;select&lt;/code&gt; в&#xA;&lt;a href=&#34;.././select&#34;&gt;10.5&lt;/a&gt; делает случайный выбор среди нескольких готовых веток. Эти механизмы объясняют, как канал&#xA;«работает». Настоящий раздел отвечает на два вопроса более высокого уровня: какую &lt;strong&gt;гарантию видимости&lt;/strong&gt; канал&#xA;даёт конкурентной программе, и на один инженерный вопрос, который поднимается нередко, — почему канал по сей&#xA;день остаётся «мьютексом плюс очередью», а не предположительно более быстрой структурой без блокировок. Первый&#xA;вопрос связывает канал с моделью памяти в &lt;a href=&#34;../../ch11sync/mem&#34;&gt;11.9&lt;/a&gt;; второй представляет собой реальный&#xA;компромисс о том, «как корректность и сопровождаемость побеждают пиковую производительность».&lt;/p&gt;</description>
    </item>
    <item>
      <title>10.7 Инженерная практика и межъязыковое сравнение</title>
      <link>/ru/part3concurrency/ch10chan/pattern/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>/ru/part3concurrency/ch10chan/pattern/</guid>
      <description>&lt;h1 id=&#34;107-инженерная-практика-и-межъязыковое-сравнение&#34;&gt;10.7 Инженерная практика и межъязыковое сравнение&lt;/h1&gt;&#xA;&lt;p&gt;В предыдущих разделах мы разобрали внутреннее устройство канала, пути отправки и получения&#xA;данных, а также реализацию &lt;code&gt;select&lt;/code&gt; на самом низком уровне. Разобравшись в механизме,&#xA;закономерно встаёт более трудный и практически ориентированный вопрос: когда следует&#xA;использовать канал, а когда — нет. Слоган Go «не общайтесь через разделяемую память;&#xA;вместо этого делитесь памятью через общение» легко прочитать как «любое разделяемое&#xA;состояние должно проходить через канал», но это не то, что имел в виду его автор. Данный&#xA;раздел сводит этот слоган к конкретному практическому правилу, сопоставляет его с более&#xA;лёгкими инструментами из главы о примитивах синхронизации (&lt;a href=&#34;../../ch11sync/readme&#34;&gt;Глава 11&lt;/a&gt;),&#xA;а затем помещает выбор Go в контекст семейства CSP, чтобы понять его конкретные координаты&#xA;в пространстве проектных решений.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
