<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF81%3AUnix_API</id>
		<title>LXF81:Unix API - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF81%3AUnix_API"/>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;action=history"/>
		<updated>2026-05-14T00:44:17Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.11.1</generator>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2569&amp;oldid=prev</id>
		<title>Yaleks: викификация</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2569&amp;oldid=prev"/>
				<updated>2008-03-17T20:21:20Z</updated>
		
		<summary type="html">&lt;p&gt;викификация&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;amp;diff=2569&amp;amp;oldid=2557&quot;&gt;(Различия между версиями)&lt;/a&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2557&amp;oldid=prev</id>
		<title>Yaleks в 20:06, 17 марта 2008</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2557&amp;oldid=prev"/>
				<updated>2008-03-17T20:06:31Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;amp;diff=2557&amp;amp;oldid=2548&quot;&gt;(Различия между версиями)&lt;/a&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2548&amp;oldid=prev</id>
		<title>Yaleks: «LXF81:IPC» переименована в «LXF81:Unix API»: унификация</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2548&amp;oldid=prev"/>
				<updated>2008-03-17T19:29:34Z</updated>
		
		<summary type="html">&lt;p&gt;«&lt;a href=&quot;/index.php/LXF81:IPC&quot; title=&quot;LXF81:IPC&quot;&gt;LXF81:IPC»&lt;/a&gt; переименована в «&lt;a href=&quot;/index.php/LXF81:Unix_API&quot; title=&quot;LXF81:Unix API&quot;&gt;LXF81:Unix API»&lt;/a&gt;: унификация&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 19:29, 17 марта 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2249&amp;oldid=prev</id>
		<title>Yaleks: /* Рекомендуемая литература */</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2249&amp;oldid=prev"/>
				<updated>2008-03-16T16:43:42Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Рекомендуемая литература&lt;/span&gt;&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 16:43, 16 марта 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 298:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 298:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;=== Рекомендуемая литература ===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;=== Рекомендуемая литература ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;# D. P. Bovet, M. Cesati, Understanding the Linux Kernel, 3rd Edition, O’Reilly, 2005&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;# D. P. Bovet, M. Cesati, Understanding the Linux Kernel, 3rd Edition, O’Reilly, 2005 &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;ISBN 0596005652&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;# W. R. Stevens, S. A. Rago, Advanced Programming in the UNIX® Environment: Second Edition, Addison Wesley Professional, 2005&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;# W. R. Stevens, S. A. Rago, Advanced Programming in the UNIX® Environment: Second Edition, Addison Wesley Professional, 2005 &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;ISBN 0201433079&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;# Стивенс У., UNIX: Взаимодействие процессов.&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; — &lt;/del&gt;СПб.: Питер, 2003&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;# Стивенс У., UNIX: Взаимодействие процессов. &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;— &lt;/ins&gt;СПб.: Питер, 2003 &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;ISBN 5-318-00535-7&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2205&amp;oldid=prev</id>
		<title>Lockal: кавычки</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=2205&amp;oldid=prev"/>
				<updated>2008-03-16T14:53:44Z</updated>
		
		<summary type="html">&lt;p&gt;кавычки&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;amp;diff=2205&amp;amp;oldid=1132&quot;&gt;(Различия между версиями)&lt;/a&gt;</summary>
		<author><name>Lockal</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=1132&amp;oldid=prev</id>
		<title>Yaleks: /* Неименованные каналы */</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=1132&amp;oldid=prev"/>
				<updated>2008-03-11T14:32:52Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Неименованные каналы&lt;/span&gt;&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 14:32, 11 марта 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 115:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 115:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;int main (int argc, char * argv[])&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;int main (int argc, char * argv[])&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;int pipedes[2];&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;int pipedes[2];&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;pid_t pid;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;pid_t pid;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;pipe(pipedes);&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;pipe(pipedes);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;pid = fork();&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;pid = fork();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;if ( pid &amp;gt; 0 )&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;if ( pid &amp;gt; 0 )&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;{&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;char *str = &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;“String &lt;/del&gt;passed via pipe\&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;n”&lt;/del&gt;;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;char *str = &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;quot;String &lt;/ins&gt;passed via pipe\&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;n&amp;quot;&lt;/ins&gt;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;close(pipedes[0]);&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;close(pipedes[0]);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;write(pipedes[1], (void *) str, strlen(str) + 1);&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;write(pipedes[1], (void *) str, strlen(str) + 1);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;close(pipedes[1]);&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;close(pipedes[1]);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;else&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;else&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;{&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;char buf[1024];&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;char buf[1024];&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;int len;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;int len;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;close(pipedes[1]);&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;close(pipedes[1]);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;while ((len = read(pipedes[0], buf, 1024)) != 0)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;while ((len = read(pipedes[0], buf, 1024)) != 0)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;write(2, buf, len);&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;write(2, buf, len);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;close(pipedes[0]);&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/ins&gt;close(pipedes[0]);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;return 0;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;return 0;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=1127&amp;oldid=prev</id>
		<title>Yaleks: /* Неименованные каналы */</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=1127&amp;oldid=prev"/>
				<updated>2008-03-11T14:22:04Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Неименованные каналы&lt;/span&gt;&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 14:22, 11 марта 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 109:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 109:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Продемонстрируем изложенное на простом примере программы pipes.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Продемонстрируем изложенное на простом примере программы pipes.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;c, использующей функции pipe() и fork().&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;c, использующей функции pipe() и fork().&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;С&lt;/del&gt;&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;C&lt;/ins&gt;&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;#include &amp;lt;string.h&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;#include &amp;lt;string.h&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 181:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 181:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;netstat через поток, связанный с дескриптором pipdes[0] (и никакой&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;netstat через поток, связанный с дескриптором pipdes[0] (и никакой&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;оболочки!).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;оболочки!).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;===Именованные каналы===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;===Именованные каналы===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Хотя в приведенном выше примере неименованные каналы используются только для передачи данных между процессами, связанными&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Хотя в приведенном выше примере неименованные каналы используются только для передачи данных между процессами, связанными&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=698&amp;oldid=prev</id>
		<title>Yaleks в 14:00, 10 марта 2008</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=698&amp;oldid=prev"/>
				<updated>2008-03-10T14:00:49Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 14:00, 10 марта 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 86:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 86:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;типа PATH и HOME и т.п. Отрицательная сторона подхода, применяемого&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;типа PATH и HOME и т.п. Отрицательная сторона подхода, применяемого&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;popen(), связана с дополнительными накладными расходы на запуск&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;popen(), связана с дополнительными накладными расходы на запуск&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;процесса оболочки в том случае, когда для выполнения команды &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;обо-&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;процесса оболочки в том случае, когда для выполнения команды &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;оболочка &lt;/ins&gt;не нужна.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;лочка &lt;/del&gt;не нужна.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Для обмена данными с внешним приложением функция popen()&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Для обмена данными с внешним приложением функция popen()&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 160:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 159:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;данных явным образом.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;данных явным образом.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Познакомившись с неименованными каналами, мы можем &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;само-&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Познакомившись с неименованными каналами, мы можем &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;самостоятельно &lt;/ins&gt;реализовать аналог функции popen() без «дополнительных&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;стоятельно &lt;/del&gt;реализовать аналог функции popen() без «дополнительных&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;расходов» (то есть, без запуска процесса оболочки). Напишем небольшую программу, которая запускает утилиту netstat, читает данные, выводимые этой утилитой, и выводит их на экран. Если бы мы использовали&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;расходов» (то есть, без запуска процесса оболочки). Напишем небольшую программу, которая запускает утилиту netstat, читает данные, выводимые этой утилитой, и выводит их на экран. Если бы мы использовали&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;для этой цели функцию popen(), то получили бы доступ к потоку вывода netstat с помощью&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;для этой цели функцию popen(), то получили бы доступ к потоку вывода netstat с помощью&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 235:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 233:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; f = fopen(FIFO_NAME, “r”);&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; f = fopen(FIFO_NAME, “r”);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Символы, передаваемые по каналу, считываются с помощью &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;фун-&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Символы, передаваемые по каналу, считываются с помощью &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;функции &lt;/ins&gt;fgetc() и выводятся на экран терминала с помощью putchar().&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;кции &lt;/del&gt;fgetc() и выводятся на экран терминала с помощью putchar().&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Каждый раз, когда пользователь сервера наживает ввод, функция&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Каждый раз, когда пользователь сервера наживает ввод, функция&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;fflush(), вызываемая сервером (см. файл typeserver.c), выполняет принудительную очистку буферов канала, в результате чего клиент&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;fflush(), вызываемая сервером (см. файл typeserver.c), выполняет принудительную очистку буферов канала, в результате чего клиент&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 257:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 254:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;организовывать взаимодействие между программами, которые не&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;организовывать взаимодействие между программами, которые не&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;только ничего не знают друг о друге, но и используют разные механизмы ввода/вывода. Сравним нашу программу typeclient и команду ls.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;только ничего не знают друг о друге, но и используют разные механизмы ввода/вывода. Сравним нашу программу typeclient и команду ls.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Казалось бы, между ними нет ничего общего – typeclient получает &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;дан-&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Казалось бы, между ними нет ничего общего – typeclient получает &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;данные&lt;/ins&gt;, используя именованный канал, а ls выводит содержимое директории в стандартный поток вывода. Однако, мы можем организовать&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;ные&lt;/del&gt;, используя именованный канал, а ls выводит содержимое директории в стандартный поток вывода. Однако, мы можем организовать&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;передачу данных от ls к typeclient с помощью всего лишь пары команд&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;передачу данных от ls к typeclient с помощью всего лишь пары команд&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;bash! В директории программы typeclient дайте команду:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;bash! В директории программы typeclient дайте команду:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 275:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 271:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;ее работу.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;ее работу.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Каналы представляют собой простое и &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;удоб-&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Каналы представляют собой простое и &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;удобное &lt;/ins&gt;средство передачи данных, которое, однако,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;ное &lt;/del&gt;средство передачи данных, которое, однако,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;подходит не во всех ситуациях. Например, с помощью каналов довольно трудно организовать обмен&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;подходит не во всех ситуациях. Например, с помощью каналов довольно трудно организовать обмен&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;асинхронными сообщениями между процессами. В следующей статье мы рассмотрим другие средства IPC Unix/&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;асинхронными сообщениями между процессами. В следующей статье мы рассмотрим другие средства IPC Unix/&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=182&amp;oldid=prev</id>
		<title>Yaleks: Новая: == Межпроцессное взаимодействие == '' часть 2 Каналы – это не только визитная карточка Санкт-Петербурга ...</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF81:Unix_API&amp;diff=182&amp;oldid=prev"/>
				<updated>2008-03-08T18:12:02Z</updated>
		
		<summary type="html">&lt;p&gt;Новая: == Межпроцессное взаимодействие == '' часть 2 Каналы – это не только визитная карточка Санкт-Петербурга ...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Межпроцессное взаимодействие ==&lt;br /&gt;
'' часть 2 Каналы – это не только визитная карточка Санкт-Петербурга и Венеции, но и основа всемогущества Unix. Освойте этот мощный механизм вместе с '''Андреем Боровским!''' ''&lt;br /&gt;
&lt;br /&gt;
Наличие в Unix-системах простых и эффективных средств&lt;br /&gt;
взаимодействия между процессами оказало программирование в Unix не менее важное влияние, чем представление объектов системы в виде файлов. Благодаря межпроцессному взаимодействию (Inter-Process Communication, IPC) разработчик (и пользователь)&lt;br /&gt;
может разбить решение сложной задачи на несколько простых операций, каждая из которых доверяется отдельной небольшой программе.&lt;br /&gt;
Последовательная обработка одной задачи несколькими простыми программами очень похожа на конвейерное производство (среди многих&lt;br /&gt;
значений английского pipeline есть и «конвейер», но в этой статье мы&lt;br /&gt;
для перевода слова pipe будем пользоваться принятым в отечественной&lt;br /&gt;
литературе термином «канал» [3]. Альтернативой конвейерному подходу являются большие монолитные пакеты, построенные по принципу&lt;br /&gt;
«все в одном». Использование набора простых утилит для решения&lt;br /&gt;
одной сложной задачи требует несколько большей квалификации со&lt;br /&gt;
стороны пользователя, но взамен предоставляет гибкость, не достижимую при использовании монолитных «монстров». Наборы утилит,&lt;br /&gt;
использующих открытые протоколы IPC, легко наращивать и модифицировать. Разбиение сложных задач на сравнительно небольшие подзадачи также позволяет снизить количество ошибок, допускаемых программистами (см. врезку). Помимо всего этого у IPC есть еще одно важное преимущество. Программы, использующие IPC, могут «общаться»&lt;br /&gt;
друг с другом практически также эффективно, как и с пользователем, в&lt;br /&gt;
результате чего появляется возможность автоматизировать выполнение&lt;br /&gt;
сложных задач. Могущество скриптовых языков Unix и Linux во многом&lt;br /&gt;
основано на возможностях IPC.&lt;br /&gt;
&lt;br /&gt;
В этой статье мы ограничимся рассмотрением IPC с помощью каналов различных типов. Предполагается, что читатели статьи являются&lt;br /&gt;
опытными пользователями Linux; во всяком случае, знают, как создаются каналы из нескольких программ с помощью командной строки. С&lt;br /&gt;
точки зрения программиста работа, программ в канале, организованном&lt;br /&gt;
с помощью символа “|”, выглядит очень просто. Данные со стандартного потока вывода одной программы перенаправляются на стандартный&lt;br /&gt;
поток ввода другой программы, чей стандартный поток вывода может&lt;br /&gt;
быть также перенаправлен. Но как быть в том случае, если необходимо&lt;br /&gt;
использовать канал внутри самой программы?&lt;br /&gt;
===Неименованные каналы===&lt;br /&gt;
Самый распространенный вариант внутрипрограммного использования&lt;br /&gt;
каналов: программа запускает другую программу и считывает данные,&lt;br /&gt;
которые та выводит в свой стандартный поток вывода. С помощью&lt;br /&gt;
этого трюка разработчик может использовать в своей программе функциональность другой программы, не вмешиваясь во внутренние детали&lt;br /&gt;
ее работы. Для решения этой задачи мы воспользуемся функциями&lt;br /&gt;
popen(3) и pclose(3). Формально эти функции подобны функциям&lt;br /&gt;
fopen(3) и fclose(3). Функция popen() запускает внешнюю программу и возвращает вызвавшему ее приложению указатель на структуру&lt;br /&gt;
FILE, связанный либо со стандартным потоком ввода, либо со стандартным потоком вывода запущенного процесса. Первый параметр функции&lt;br /&gt;
popen() – строка, содержащая команду, запускающую внешнюю программу. Второй параметр определяет, какой из стандартных потоков&lt;br /&gt;
(вывода или ввода) будет возвращен. Аргумент “w” соответствует потоку&lt;br /&gt;
ввода запускаемой программы, в этом случае приложение, вызвавшее&lt;br /&gt;
popen(), записывает данные в поток. Аргумент “r” соответствует потоку&lt;br /&gt;
вывода. Функция pclose() служит для завершения работы с внешним&lt;br /&gt;
приложением и закрытием канала. Для демонстрации работы с функциями popen()/pclose() мы напишем небольшую программу makelog&lt;br /&gt;
(полный текст программы можно найти на диске в файле makelog.&lt;br /&gt;
c) Программа makelog выполняет команду оболочки, переданную ей в&lt;br /&gt;
качестве параметра и записывает данные, выводимые этой командой,&lt;br /&gt;
одновременно на стандартный терминал и в файл log.txt (аналогичными функциями обладает стандартная команда tee). Например, если&lt;br /&gt;
скомпилировать программу:&lt;br /&gt;
 gcc makelog.c -o makelog&lt;br /&gt;
&lt;br /&gt;
а затем скомандовать&lt;br /&gt;
 makelog “ls -al”&lt;br /&gt;
&lt;br /&gt;
на экране терминала будут распечатаны данные, выводимые командой оболочки ls -al, а в рабочей директории программы makelog будет&lt;br /&gt;
создан файл log.txt, содержащий те же данные. Кавычки вокруг команды оболочки нужны для того, чтобы программа makelog получала строку&lt;br /&gt;
вызова команды как один параметр командной строки.&lt;br /&gt;
&lt;br /&gt;
Как читатель наверняка уже догадался, изюминка программы&lt;br /&gt;
makelog заключается в использовании функции popen(). Рассмотрим&lt;br /&gt;
фрагмент исходного текста программы:&lt;br /&gt;
 f = popen(argv[1], “r”);&lt;br /&gt;
&lt;br /&gt;
Эта операция очень похожа на открытие обычного файла для чтения.&lt;br /&gt;
Переменная f имеет тип FILE *, но в параметре argv[1] функции popen&lt;br /&gt;
передается не имя файла, а команда на запуск программы или команды оболочки, например, “ls -al”. Если вызов popen() был успешен, мы&lt;br /&gt;
можем считывать данные, выводимые запущенной командой, с помощью обычной функции fread(3):&lt;br /&gt;
 fread(buf, 1, BUF_SIZE, f)&lt;br /&gt;
&lt;br /&gt;
Особенность функции popen() заключается в том, что эта функция&lt;br /&gt;
не возвращает NULL, даже если переданная ей команда не является&lt;br /&gt;
корректной. Самый простой способ обнаружить ошибку в этой ситуации – попытаться прочесть данные из потока вывода. Если в потоке&lt;br /&gt;
вывода нет данных (fread() возвращает значение 0), значит произошла ошибка. Для вывода данных, прочитанных с помощью fread(), на&lt;br /&gt;
терминал мы используем функцию write() с указанием дескриптора&lt;br /&gt;
стандартного потока вывода:&lt;br /&gt;
 write(1, buf, len);&lt;br /&gt;
&lt;br /&gt;
Параллельно эти же данные записываются в файл на диске. По&lt;br /&gt;
окончании чтения данных открытый канал нужно закрыть:&lt;br /&gt;
 pclose(f);&lt;br /&gt;
&lt;br /&gt;
Следует иметь в виду, что pclose() вернет управление вызывающему потоку только после того, как запущенное с помощью popen()&lt;br /&gt;
приложение завершит свою работу.&lt;br /&gt;
&lt;br /&gt;
В заключение отметим еще одну особенность функции popen().&lt;br /&gt;
Для выполнения переданной ей команды popen() сперва запускает&lt;br /&gt;
собственный экземпляр оболочки, что, с одной стороны хорошо, а с&lt;br /&gt;
другой – не очень. Хорошо это потому, что при вызове popen() автоматически выполняются внутренние операции оболочки (такие как обработка шаблонов имен файлов), используются переменные окружения&lt;br /&gt;
типа PATH и HOME и т.п. Отрицательная сторона подхода, применяемого&lt;br /&gt;
popen(), связана с дополнительными накладными расходы на запуск&lt;br /&gt;
процесса оболочки в том случае, когда для выполнения команды обо-&lt;br /&gt;
лочка не нужна.&lt;br /&gt;
&lt;br /&gt;
Для обмена данными с внешним приложением функция popen()&lt;br /&gt;
использует каналы неявным образом. В своих программах мы можем&lt;br /&gt;
использовать каналы и непосредственно. Наиболее распространенный&lt;br /&gt;
тип каналов, – неименованные однонаправленные каналы (anonymous&lt;br /&gt;
pipes), создаваемые функцией pipe(2). На уровне интерфейса программирования такой канал представляется двумя дескрипторами&lt;br /&gt;
файлов, один из которых служит для чтения данных, а другой – для&lt;br /&gt;
записи. Каналы не поддерживают произвольный доступ, т. е. данные&lt;br /&gt;
могут считываться только в том же порядке, в котором они записывались. Неименованные каналы используются преимущественно вместе с&lt;br /&gt;
функцией fork(2) и служат для обмена данными между родительским&lt;br /&gt;
и дочерним процессами. Для организации подобного обмена данными,&lt;br /&gt;
сначала, с помощью функции pipe(), создается канал. Функции pipe()&lt;br /&gt;
передается единственный параметр – массив типа int, состоящий&lt;br /&gt;
из двух элементов. В первом элементе массива функция возвращает&lt;br /&gt;
дескриптор файла, служащий для чтения данных из канала (выход&lt;br /&gt;
канала), а во втором – дескриптор для записи (вход). Затем, с помощью&lt;br /&gt;
функции fork() процесс «раздваивается». Дочерний процесс наследует от родительского процесса оба дескриптора, открытых с помощью&lt;br /&gt;
pipe(), но, также как и родительский процесс, он должен использовать&lt;br /&gt;
только один из дескрипторов. Направление передачи данных между&lt;br /&gt;
родительским и дочерним процессом определяется тем, какой дескриптор будет использоваться родительским процессом, а какой – дочерним.&lt;br /&gt;
Продемонстрируем изложенное на простом примере программы pipes.&lt;br /&gt;
c, использующей функции pipe() и fork().&lt;br /&gt;
&amp;lt;source lang=&amp;quot;С&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
int main (int argc, char * argv[])&lt;br /&gt;
{&lt;br /&gt;
int pipedes[2];&lt;br /&gt;
pid_t pid;&lt;br /&gt;
pipe(pipedes);&lt;br /&gt;
pid = fork();&lt;br /&gt;
if ( pid &amp;gt; 0 )&lt;br /&gt;
{&lt;br /&gt;
char *str = “String passed via pipe\n”;&lt;br /&gt;
close(pipedes[0]);&lt;br /&gt;
write(pipedes[1], (void *) str, strlen(str) + 1);&lt;br /&gt;
close(pipedes[1]);&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
char buf[1024];&lt;br /&gt;
int len;&lt;br /&gt;
close(pipedes[1]);&lt;br /&gt;
while ((len = read(pipedes[0], buf, 1024)) != 0)&lt;br /&gt;
write(2, buf, len);&lt;br /&gt;
close(pipedes[0]);&lt;br /&gt;
}&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба дескриптора канала хранятся в переменной pipedes. После&lt;br /&gt;
вызова fork() процесс раздваивается и родительский процесс (тот, в&lt;br /&gt;
котором fork() вернула ненулевое значение, равное, кстати, PID дочернего процесса) закрывает дескриптор, открытый для чтения, и записывает данные в канал, используя дескриптор, открытый для записи&lt;br /&gt;
(pipedes[1]). Дочерний процесс (в котором fork() вернула 0) первым&lt;br /&gt;
делом закрывает дескриптор, открытый для записи, и затем считывает данные из канала, используя дескриптор, открытый для чтения&lt;br /&gt;
(pipedes[0]). Назначение дескрипторов легко запомнить, сопоставив их с аббревиатурой I/O (первый дескриптор – для чтения (input),&lt;br /&gt;
второй – для записи (output)). Стандарт POSIX предписывает, чтобы&lt;br /&gt;
каждый процесс, получивший оба канальных дескриптора, закрывал&lt;br /&gt;
тот дескриптор, который ему не нужен, перед тем, как начать работу с&lt;br /&gt;
другим дескриптором, и, хотя в системе Linux этим требованием можно&lt;br /&gt;
пренебречь, лучше все же придерживаться строгих правил.&lt;br /&gt;
&lt;br /&gt;
В нашем примере нам не нужно беспокоиться о синхронизации&lt;br /&gt;
передачи данных, поскольку ядро системы выполнит всю трудную&lt;br /&gt;
работу за нас. Но в жизни встречаются и не столь тривиальные случаи.&lt;br /&gt;
Например, ничто не мешает нам создать несколько дочерних процессов&lt;br /&gt;
с помощью нескольких вызовов fork(). Все эти процессы могут использовать один и тот же канал, при условии, что каждый процесс использует только один из дескрипторов pipdes, согласно его назначению. В&lt;br /&gt;
этой ситуации нам пришлось бы выполнять синхронизацию передачи&lt;br /&gt;
данных явным образом.&lt;br /&gt;
&lt;br /&gt;
Познакомившись с неименованными каналами, мы можем само-&lt;br /&gt;
стоятельно реализовать аналог функции popen() без «дополнительных&lt;br /&gt;
расходов» (то есть, без запуска процесса оболочки). Напишем небольшую программу, которая запускает утилиту netstat, читает данные, выводимые этой утилитой, и выводит их на экран. Если бы мы использовали&lt;br /&gt;
для этой цели функцию popen(), то получили бы доступ к потоку вывода netstat с помощью&lt;br /&gt;
 popen(“netstat”, “r”);&lt;br /&gt;
&lt;br /&gt;
и скопировали данные на экран. Этот способ прост, но не эффективен. Мы напишем другую программу (файл printns.c). Структура этой&lt;br /&gt;
программы та же, что и в предыдущем примере, только теперь родительский процесс читает данные с помощью канала. Самое интересное&lt;br /&gt;
происходит в дочернем процессе, где выполняется последовательность&lt;br /&gt;
функций:&lt;br /&gt;
 close(pipedes[0]);&lt;br /&gt;
 dup2(pipedes[1], 1);&lt;br /&gt;
 execve(“/bin/netstat”, NULL, NULL);&lt;br /&gt;
&lt;br /&gt;
С помощью функции dup2(2) мы перенаправляем стандартный&lt;br /&gt;
поток вывода дочернего процесса (дескриптор стандартного потока&lt;br /&gt;
вывода равен 1) в канал, используя дескриптор pipdes[1], открытый&lt;br /&gt;
для записи. Далее, с помощью функции execve(2) мы заменяем образ&lt;br /&gt;
дочернего процесса процессом netstat (обратите внимание, что поскольку в нашем распоряжении нет оболочки с ее переменной окружения&lt;br /&gt;
PATH, путь к исполнимому файлу netstat нужно указывать полностью).&lt;br /&gt;
В результате родительский процесс может читать стандартный вывод&lt;br /&gt;
netstat через поток, связанный с дескриптором pipdes[0] (и никакой&lt;br /&gt;
оболочки!).&lt;br /&gt;
===Именованные каналы===&lt;br /&gt;
Хотя в приведенном выше примере неименованные каналы используются только для передачи данных между процессами, связанными&lt;br /&gt;
«родственными узами», существует возможность использовать их и для&lt;br /&gt;
передачи данных между совершенно разными процессами. Для этого&lt;br /&gt;
нужно организовать передачу дескрипторов канала между неродственными процессами, как это описано, например, в [2]. Однако передача&lt;br /&gt;
дескрипторов стороннему процессу носит, скорее, характер трюка (или&lt;br /&gt;
«хака»), и мы на ней останавливаться не будем. Для передачи данных&lt;br /&gt;
между неродственными процессами мы воспользуемся механизмом&lt;br /&gt;
именованных каналов (named pipes), который позволяет каждому&lt;br /&gt;
процессу получить свой, «законный» дескриптор канала. Передача&lt;br /&gt;
данных в этих каналах (как, впрочем, и в однонаправленных неименованных каналах) подчиняется принципу FIFO (первым записан – первым&lt;br /&gt;
прочитан), поэтому в англоязычной литературе иногда можно встретить&lt;br /&gt;
названия FIFO pipes или просто FIFOs. Именованные каналы отличаются от неименованных наличием имени (странно, не правда ли?), то&lt;br /&gt;
есть идентификатора канала, потенциально видимого всем процессам&lt;br /&gt;
системы. Для идентификации именованного канала создается файл&lt;br /&gt;
специального типа pipe. Это еще один представитель семейства виртуальных файлов Unix, не предназначенных для хранения данных (размер&lt;br /&gt;
файла канала всегда равен нулю). Файлы именованных каналов являются элементами VFS, как и обычные файлы Linux, и для них действуют&lt;br /&gt;
те же правила контроля доступа. Файлы именованных каналов создаются функцией mkfifo(3). Первый параметр этой функции – строка,&lt;br /&gt;
в которой передается имя файла, идентифицирующего канал, второй&lt;br /&gt;
параметр – маска прав доступа к файлу. Функции mkfifo() создает&lt;br /&gt;
канал и файл соответствующего типа. Если указанный файл канала уже&lt;br /&gt;
существует, mkfifo() возвращает -1, (переменная errno принимает значение EEXIST). После создания файла канала процессы, участвующие&lt;br /&gt;
в обмене данными, должны открыть этот файл либо для записи, любо&lt;br /&gt;
для чтения. После закрытия файла канала, файл (и канал) продолжают&lt;br /&gt;
существовать. Для того чтобы закрыть сам канал, нужно удалить его&lt;br /&gt;
файл, например с помощью последовательных вызовов unlink(2).&lt;br /&gt;
&lt;br /&gt;
Рассмотрим работу именованного канала на примере простой системы клиент-сервер. Программа-сервер создает канал и передает в него&lt;br /&gt;
текст, вводимый пользователем с клавиатуры. Программа-клиент читает&lt;br /&gt;
текст и выводит его на терминал. Программы из этого примера можно&lt;br /&gt;
рассматривать как упрощенный вариант системы мгновенного обмена сообщениями между пользователями многопользовательской ОС.&lt;br /&gt;
Исходный текст программы-сервера хранится в файле typeserver.c.&lt;br /&gt;
Вызов функции mkfifo() создает файл-идентификатор канала в рабочей директории программы:&lt;br /&gt;
 mkfifo(FIFO_NAME, 0600);&lt;br /&gt;
&lt;br /&gt;
где FIFO_NAME – макрос, задающий имя файла канала (в нашем&lt;br /&gt;
случае – “./fifofile”).&lt;br /&gt;
&lt;br /&gt;
В качестве маски доступа мы используем восьмеричное значение&lt;br /&gt;
0600, разрешающее процессу с аналогичными реквизитами пользователя чтение и запись (можно было бы использовать маску 0666, но на&lt;br /&gt;
мы на всякий случай воздержимся от упоминания Числа Зверя, пусть&lt;br /&gt;
даже восьмеричного, в нашей программе). Для краткости мы не проверяем значение, возвращенное mkfifo(), на предмет ошибок. В результате вызова mkfifo() с заданными параметрами в рабочей директории&lt;br /&gt;
программы должен появиться специальный файл fifofile. Файл-менеджер KDE отображает файлы канала с помощью красивой пиктограммы,&lt;br /&gt;
изображающей приоткрытый водопроводный кран. Далее в программесервере мы просто открываем созданный файл для записи:&lt;br /&gt;
 f = fopen(FIFO_NAME, “w”);&lt;br /&gt;
&lt;br /&gt;
Считывание данных, вводимых пользователем, выполняется с помощью getchar(), а с помощью функции fputc() данные передаются в&lt;br /&gt;
канал. Работа сервера завершается, когда пользователь вводит символ&lt;br /&gt;
“q”. Исходный текст программы-клиента можно найти в файле typeclient.&lt;br /&gt;
c. Клиент открывает файл fifofile для чтения как обычный файл:&lt;br /&gt;
 f = fopen(FIFO_NAME, “r”);&lt;br /&gt;
&lt;br /&gt;
Символы, передаваемые по каналу, считываются с помощью фун-&lt;br /&gt;
кции fgetc() и выводятся на экран терминала с помощью putchar().&lt;br /&gt;
Каждый раз, когда пользователь сервера наживает ввод, функция&lt;br /&gt;
fflush(), вызываемая сервером (см. файл typeserver.c), выполняет принудительную очистку буферов канала, в результате чего клиент&lt;br /&gt;
считывает все переданные символы. Получение символа “q” завершает&lt;br /&gt;
работу клиента.&lt;br /&gt;
&lt;br /&gt;
Скомпилируйте программы typeserver.c и typeclient.c в одной&lt;br /&gt;
директории. Запустите сначала сервер, потом клиент в разных окнах терминала. Печатайте текст в окне сервера. После каждого нажатия клавиши&lt;br /&gt;
[Enter] клиент должен отображать строку, напечатанную на сервере.&lt;br /&gt;
&lt;br /&gt;
Для создания файла FIFO можно воспользоваться также функцией&lt;br /&gt;
mknod(2), предназначенной для создания специальных файлов различных типов (FIFO, сокеты, файлы устройств и обычные файлы для&lt;br /&gt;
хранения данных). В нашем случае вместо&lt;br /&gt;
 mkfifo(fname, 0600);&lt;br /&gt;
&lt;br /&gt;
можно было бы написать&lt;br /&gt;
 mknod(fname, S_IFIFO, 0);&lt;br /&gt;
&lt;br /&gt;
Одной из сильных сторон Unix/Linux IPC является возможность&lt;br /&gt;
организовывать взаимодействие между программами, которые не&lt;br /&gt;
только ничего не знают друг о друге, но и используют разные механизмы ввода/вывода. Сравним нашу программу typeclient и команду ls.&lt;br /&gt;
Казалось бы, между ними нет ничего общего – typeclient получает дан-&lt;br /&gt;
ные, используя именованный канал, а ls выводит содержимое директории в стандартный поток вывода. Однако, мы можем организовать&lt;br /&gt;
передачу данных от ls к typeclient с помощью всего лишь пары команд&lt;br /&gt;
bash! В директории программы typeclient дайте команду:&lt;br /&gt;
 mknod fifofile p&lt;br /&gt;
&lt;br /&gt;
Эта команда создаст файл канала fifofile также, как это сделала&lt;br /&gt;
бы программа typeserver.&lt;br /&gt;
&lt;br /&gt;
Запустите программу typeclient, а затем в другом окне терминала&lt;br /&gt;
дайте команду, наподобие&lt;br /&gt;
 ls -al &amp;gt; /path/fifofile&lt;br /&gt;
&lt;br /&gt;
где /path/fifofile – путь к файлу FIFO. В результате,&lt;br /&gt;
программа typeclient распечатает содержимое соответствующей директории. Главное, чтобы в потоке&lt;br /&gt;
данных не встретился символ “q”, завершающий&lt;br /&gt;
ее работу.&lt;br /&gt;
&lt;br /&gt;
Каналы представляют собой простое и удоб-&lt;br /&gt;
ное средство передачи данных, которое, однако,&lt;br /&gt;
подходит не во всех ситуациях. Например, с помощью каналов довольно трудно организовать обмен&lt;br /&gt;
асинхронными сообщениями между процессами. В следующей статье мы рассмотрим другие средства IPC Unix/&lt;br /&gt;
Linux – очереди сообщений и семафоры.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Закон Брукса===&lt;br /&gt;
Фредерик Брукс, автор книги «Мифический человеко-месяц», высказал предположение (известное как «закон Брукса»), что количество&lt;br /&gt;
ошибок в проекте должно быть пропорционально квадрату числа&lt;br /&gt;
участников проекта, тогда как объем полезной работы при увеличении числа участников проекта растет линейно. Закон Брукса означал,&lt;br /&gt;
что на определенном этапе развития проекта любая попытка привлечь к разработке новых программистов приводит лавинообразному&lt;br /&gt;
росту числа ошибок (а значит, все больше и больше работы требуется&lt;br /&gt;
на их выявление и исправление). Если бы закон Брукса выполнялся,&lt;br /&gt;
то для всех проектов существовал бы верхний порог сложности, при&lt;br /&gt;
попытке превысить который КПД разработки начинал бы стремительно падать. Что же касается открытой модели разработки ПО, то она,&lt;br /&gt;
с точки зрения закона Брукса, была бы невозможна в принципе. Для&lt;br /&gt;
того, чтобы понять, в чем Ф. Брукс ошибался, следует рассмотреть&lt;br /&gt;
исходные посылки его рассуждений. Закон Брукса основан на двух&lt;br /&gt;
предположениях: а) ошибки чаще возникают на стыке элементов&lt;br /&gt;
проекта, выполняемых разными разработчиками (соответственно,&lt;br /&gt;
чем больше таких «швов», тем больше ошибок); б) модель взаимодействия разработчиков представляет собой полный граф (то есть,&lt;br /&gt;
каждый разработчик взаимодействует со всеми остальными участниками проекта), число ребер которого пропорционально квадрату&lt;br /&gt;
числа вершин. Ни то, ни другое утверждение, вообще говоря, неверно. В частности, при программировании «канальных» утилит всем&lt;br /&gt;
участникам проекта нет надобности непосредственно контактировать&lt;br /&gt;
между собой. Каждая группа разработчиков должна следовать только&lt;br /&gt;
фиксированному протоколу обмена данными между программами,&lt;br /&gt;
так что в этом случае число ошибок подчиняется линейной, а не&lt;br /&gt;
квадратичной, зависимости.&lt;br /&gt;
&lt;br /&gt;
===Как канал передает данные===&lt;br /&gt;
Для передачи данных по каналу используются специальные объекты ядра системы, называемые буферами каналов (pipe buffers). Даже если предыдущая&lt;br /&gt;
запись заполнила буфер не полностью, повторная&lt;br /&gt;
запись данных в буфер становится возможной только&lt;br /&gt;
после того, как прежде записанные данные будут прочитаны. Это означает, что если разные процессы, пишущие данные в один и тот же канал, передают данные блоками, размеры которых не превышают объем&lt;br /&gt;
буферов, данные из блоков разных процессов не&lt;br /&gt;
будут перемешиваться между собой. Использование&lt;br /&gt;
этой особенности каналов существенно упрощает&lt;br /&gt;
синхронизацию передачи данных. Узнать размер буфера можно с помощью вызова функции&lt;br /&gt;
 fpathconf(pipedes, _PC_PIPE_BUF)&lt;br /&gt;
&lt;br /&gt;
где pipedes – дескриптор канала. На архитектуре IA32 размер буфера составляет 4 килобайта.&lt;br /&gt;
Начиная с ядра 2.6.11, каждый канал может использовать до 16 буферов, что существенно повышает&lt;br /&gt;
производительность каналов.&lt;br /&gt;
&lt;br /&gt;
===Рекомендуемая литература===&lt;br /&gt;
# D. P. Bovet, M. Cesati, Understanding the Linux Kernel, 3rd Edition, O’Reilly, 2005&lt;br /&gt;
# W. R. Stevens, S. A. Rago, Advanced Programming in the UNIX® Environment: Second Edition, Addison Wesley Professional, 2005&lt;br /&gt;
# Стивенс У., UNIX: Взаимодействие процессов. – СПб.: Питер, 2003&lt;/div&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	</feed>