<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>В лабиринте извилин &#187; *nix</title>
	<atom:link href="http://www.charnad.com/blog/category/programming/nix/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.charnad.com</link>
	<description>Блог-центр им. CharnaD</description>
	<lastBuildDate>Wed, 18 Jan 2012 14:52:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PHP: эксклюзивный счетчик в Shared Memory</title>
		<link>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/</link>
		<comments>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 12:41:14 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ipc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[shared memory]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=992</guid>
		<description><![CDATA[Я надеюсь что вы уже прочитали вводную статью про многопоточность в PHP, или вам это просто не требуется. Теперь я расскажу про счетчик, который будет доступен для потоков приложения, при этом доступ к нему будет эксклюзивным. Разделяемая память - особая область памяти, которая доступа ВСЕМ процессам операционной системы. Доступ к определенному сегменту можно получить с [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Я надеюсь что вы уже прочитали вводную статью про <a href="http://www.charnad.com/blog/mnogopotochnost-na-php/">многопоточность в PHP</a>, или вам это просто не требуется. Теперь я расскажу про счетчик, который будет доступен для потоков приложения, при этом доступ к нему будет эксклюзивным.</p>
<p><span id="more-992"></span></p>
<p>Разделяемая память - особая область памяти, которая доступа ВСЕМ процессам операционной системы. Доступ к определенному сегменту можно получить с помощью двух параметров: имени существующего файла и одного символа, который будет ключом System V IPC. Это нужно для того, чтобы несколько сегментов могли быть выделены основываясь на одном и том же файле. Звучит пока очень туманно, но сейчас я приведу пример, и надеюсь все станет понятно.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$t_key</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ftok</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'g'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$shmid</span> <span style="color: #339933;">=</span> <span style="color: #990000;">shmop_open</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$t_key</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'c'</span><span style="color: #339933;">,</span> <span style="color: #208080;">0755</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">64</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">shmop_write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shmid</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">shmop_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shmid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Первой командой, специальной функцией ftok мы получили ключ, по которому будем получать доступ к сегменту разделяемой памяти. Первым параметром мы передали ему имя файла скрипта, а вторым букву 'g'. Почему 'g'? А просто так, можно взять любой символ.<br />
Во второй строке мы собственно открываем доступ к сегменту памяти. Первый параметр - наш ключ, второй параметр 'c' - флаг указывающий на то, что мы создаем сегмент памяти, при том, если он уже существуем - он открывается на чтение/запись. Третий параметр - права на доступ, четвертый - размер в байтах.<br />
В третьей строке мы записываем туда единицу, последний параметр - смещение.<br />
И наконец закрываем сегмент.<br />
Теперь по адресу, который определяется файлом скрипта и буквой 'g' в сегменте размером 64 байта лежит единица, и ее может достать любой процесс.</p>
<p>Теперь представим, что у нас программа работает в 50 потоков, она обрабатывает файл строчка за строчкой. Мы не хотим, чтобы программа два раза обрабатывала одну строку, поэтому кладем в разделяемую память номер строки, которая была обработана последней. И каждый процесс перед тем, как считать строчку берет из разделяемой памяти номер последней обработанной строки, прибавляет единицу, записывает обратно в разделяемую память и идет обрабатывать эту строчку. Следующий процесс возьмет уже строчку с номером на один больше. Все хорошо, все радуются, работает быстро. Однако случается так, что два процесса одновременно решили взять значение из памяти и взяли одинаковое значение и записали одинаковое. А представьте, что сразу 50 процессов одновременно считают значение. В общем дело ясное, что нам надо ограничить доступ к памяти одним процессом.</p>
<p>Как раз для таких случаев придуманы семафоры. Семафор (semaphore) - это такая сущность, которая позволяет ограниченному количеству процессов одновременно получать "зеленый свет" на выполнение чего-либо. Семафор, у которого такое количество равно 1 называется мьютексом (mutex). Именно мьютекс позволит нам не допускать в наш сегмент памяти больше одного процесса и остановит анархию.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$sem</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sem_get</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">ftok</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'g'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">sem_acquire</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sem</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//тут может быть только один процесс</span>
<span style="color: #990000;">sem_release</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sem</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Мы получаем ключ для семафора точно таким же образом, как и для разделяемой памяти. Третий параметр - автоматическое "отпускание" семафора, если поток, который был впущен завершился. Те потоки, которые попытаются получить доступ к семафору, будут блокированы до тех пор, пока семафор не освободится. Это похоже на очередь в туалет. Один внутри, остальные снаружи. Один выходит, другой заходит и закрывается, другие продолжают ждать.
</p>
<p>Таким образом, создав ячейку памяти и создав семафор мы получаем счетчик, который позволит нам обрабатывать файл построчно не боясь, что одна строка будет обработана два раза. Для использования этого принципа я сделал класс Counter, который работает в моем многопоточном приложении. Взять его можно <a href="http://pastebin.org/86576">вот здесь</a>. А тут я приведу пример использования:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Ноль это наше начальное состояние счетчика</span>
<span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span>_new<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Порождаем потомков</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> PROCESS_AMOUNT<span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Error spawning new process'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//Родительский процесс у нас ничего не будет делать</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//Первый параметр - имя счетчика, и заодно часть ключа</span>
        <span style="color: #666666; font-style: italic;">//Второй параметр - увеличивать ли значение счетчика</span>
        <span style="color: #666666; font-style: italic;">//В данном случае мы просто читаем значение</span>
        <span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">//TOTAL_LINES - количество строк в файле</span>
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$counter</span> <span style="color: #339933;">&lt;</span> TOTAL_LINES<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">//Берем значение счетчика и увеличиваем его на 1</span>
            <span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">//Обарабатываем файл</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Многопоточность на PHP</title>
		<link>http://www.charnad.com/blog/mnogopotochnost-na-php/</link>
		<comments>http://www.charnad.com/blog/mnogopotochnost-na-php/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 12:05:36 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ipc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=988</guid>
		<description><![CDATA[Хочу рассказать вам про многопоточные приложения, взаимодействие процессов (IPC) и применение всего этого на PHP. В качестве примера мы возьмем счетчик с эксклюзивным доступом, доступный для всех процессов. Что такое многопоточность? Это способ разделения программы на отдельные сущности (процессы и треды(threads)) для обеспечивания параллельности выполнения. Зачем это нужно? Для ускорения работы. Ведь открывая какой-нибудь сайт [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Хочу рассказать вам про многопоточные приложения, взаимодействие процессов (IPC) и применение всего этого на PHP. В качестве примера мы возьмем счетчик с эксклюзивным доступом, доступный для всех процессов.</p>
<p><span id="more-988"></span></p>
<p>Что такое многопоточность? Это способ разделения программы на отдельные сущности (процессы и треды(threads)) для обеспечивания параллельности выполнения. Зачем это нужно? Для ускорения работы. Ведь открывая какой-нибудь сайт вы не хотите ждать пока сервер последовательно откроет его всем, кто запросил его до вас. Вы хотите сразу, поэтому сервер выделяет отдельный процесс или поток для обработки вашего запроса. </p>
<p>Сначала немного про многопточность в PHP. PHP не многопоточный язык, PHP не умеет работать с тредами. Однако мы можем использовать системные вызовы операционной системы для создания процессов. Это как если бы мы просто запускали PHP-CLI несколько раз. Основная команда pcntl_fork разделяет выполнение программы на 2 части: родительскую и дочернюю, при этом эта команда вернет идентификатор процесса. Если вернулся -1, значит произошла ошибка, если 0, значит мы в дочернем потоке, если число - значит в родительском. </p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Произошла ошибка'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #666666; font-style: italic;">// Мы в родительском потоке</span>
     pcntl_wait<span style="color: #009900;">&#40;</span><span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//Ждем выполнения потомка</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #666666; font-style: italic;">// Мы в потоке потомке</span>
     <span style="color: #666666; font-style: italic;">// Делаем что-нибудь</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>В этом примере мы разделили программу на 2 части. В родительском процессе мы ожидаем завершения дочернего, чтобы тот доложил об успешном завершении. В противном случае он останется висеть в системе, как процесс-зомби. А если мы хотим не 2 потока, а больше? Тогда вызываем pcntl_fork несколько раз.</p>
<p>Приведу пример, как можно использовать pcntl_fork для "демонизации" процесса. Демон (daemon) - процесс выполняющийся в фоновом режиме. Это бывает очень удобно для программ, которые выполняются долгое время и не требуют прямого общения с пользователем. В Windows службы - аналог демонов в *nix системах. Итак, у вас есть программа на PHP, выполняющаяся в командной строке и вы хотите, чтобы она работала в фоне. Конечно, вы всегда можете сделать так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">nohup</span> php script.php <span style="color: #000000; font-weight: bold;">&amp;</span></pre></div></div>

<p>Это запустит вашу программу в фоновом режиме, а весь вывод будет перенаправлять в nohup.out. Более того, программа не завершится с выходом пользователя из системы. Но для демонов более правильный вариант создать процесс-потомок, закрыть родительский процесс (да-да, почти как зомби), только мы еще назначим наш дочерний поток "лидером сессии", то есть он сам сможет порождать дочерние потоки.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Demonization</span>
<span style="color: #000088;">$child_pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Если мы получили дочерний id, </span>
<span style="color: #666666; font-style: italic;">// то мы в родительском потоке</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$child_pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">//Здесь мы уже в потомке, а родитель был закрыл</span>
<span style="color: #990000;">posix_setsid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Таким образом мы получим независимо выполняющуюся программу. Завершить ее можно командой kill pid, где pid - идентификатор процесса. Тот самый, который возвращается в родительский поток и представляет собой целое неотрицательное число, уникальное в системе.
</p>
<p>Возникает вопрос, зачем же нужны threads, если есть процессы? Дело в том, что треды выполняются в том же контексте, что и породивший его процесс, то есть все треды имеют общие ресурсы, например открытые файлы. Закрыв файловый дескриптор в одном треде, вы получите ошибку в другом, если попытаетесь прочитать этот файл с тем же дескриптором. В свою очередь процессам нужен особый способ обмениваться данными, если вы хотите открыть один и тот же файл в разных процессах. Для такого общения есть множество инструментов. Один из основных - сигналы.</p>
<p>Сигналы - это системные вызовы, влияющие на поведение процессов. Сигнал может завершить, приостановить, или послать особый сигнал, определенный пользователем. Помимо сигналов есть разделяемая память (shared memory) и семафоры (semaphores). Более подробно о них, и вообще об устройстве posix совместимых операционных систем советую вам поискать в интернете. Это было краткое введение в тему, для подготовки к следующей статье про <a href="http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/">счетчик в shared memory</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/mnogopotochnost-na-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ошибка PDO Invalid Argument и Unix socket</title>
		<link>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/</link>
		<comments>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 14:56:32 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=910</guid>
		<description><![CDATA[Такая ошибка возникла у меня после перехода на PHP 5.3. Решение я нашел на http://stackoverflow.com, можете там посмотреть, чтобы узнать про эту ошибку более подробно. Выглядит она вот так: Warning: PDO::__construct&#40;&#41; &#91;pdo.--construct&#93;: &#91;2002&#93; Invalid argument &#40;trying to connect via unix://&#41; in /home/blah-blah-blah.php on line 9 &#160; Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Такая ошибка возникла у меня после перехода на PHP 5.3. Решение я нашел на http://stackoverflow.com, можете там посмотреть, чтобы узнать про эту ошибку более подробно. Выглядит она вот так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Warning: PDO::__construct<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>pdo.--construct<span style="color: #7a0874; font-weight: bold;">&#93;</span>: <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2002</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> Invalid argument <span style="color: #7a0874; font-weight: bold;">&#40;</span>trying to connect 
via unix:<span style="color: #000000; font-weight: bold;">//</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php on line <span style="color: #000000;">9</span>
&nbsp;
Fatal error: Uncaught exception <span style="color: #ff0000;">'PDOException'</span> with message <span style="color: #ff0000;">'SQLSTATE[HY000] [2002]
Invalid argument'</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php:<span style="color: #000000;">9</span> Stack trace: <span style="color: #666666; font-style: italic;">#0</span>
<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: PDO-<span style="color: #000000; font-weight: bold;">&gt;</span>__construct<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">'mysql:host=localhost;dbname=db'</span>, <span style="color: #ff0000;">'USER'</span>, 
<span style="color: #ff0000;">'PASSWORD'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">#1 {main} thrown in /home/blah-blah-blah.php on line 9</span></pre></div></div>

<p>Решается она так: вместо localhost, при написании DSN для PDO пишите 127.0.0.1. А так же стоит указать путь к сокету MySQL в php.ini: pdo_mysql.default_socket=/var/run/mysqld/mysql.sock</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: Получить строку по номеру</title>
		<link>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/</link>
		<comments>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 13:59:25 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=884</guid>
		<description><![CDATA[Мне нужно было получать строку из файла по порядковому номеру. То есть первую, десятую, 390815-ую, и т.д. Сначала мне хватало цикла fgets, который прокручивал до нужной строки. На строке 500000 такой способ у меня занимал уже почти минуту, что явно плохо. Stream_get_line был совем не быстрее, а даже медленнее процентов на 30. Первый из костылей, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" title="PHP" src="http://static.php.net/www.php.net/images/php.gif" alt="" width="120" height="67" />
<p>Мне нужно было получать строку из файла по порядковому номеру. То есть первую, десятую, 390815-ую, и т.д. Сначала мне хватало цикла fgets, который прокручивал до нужной строки. На строке 500000 такой способ у меня занимал уже почти минуту, что явно плохо. Stream_get_line был совем не быстрее, а даже медленнее процентов на 30.</p>
<p>Первый из костылей, пришедших мне в голову был fseek до значения в 500000 строк (посчитал байты), а оттуда уже крутил fgets. Но так как у меня идет обработка до 100 тысяч строк в сутки, то через пару дней опять пришлось высчитывать смещение для fseek. Опять же, требовался другой выход. И я его таки нашел.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getFileLine<span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;head -n <span style="color: #006699; font-weight: bold;">$line</span> <span style="color: #006699; font-weight: bold;">$file</span> | tail -n 1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Head берет N первых строк файла, tail N последних. Все гениальное просто. 1 миллионная строка берется из файла за 1.027 сек, 40 миллионная - 30 секунд, что очевидно быстрее прокручивания fgets.  (Конечно, если не прыгать fseek до 40 миллионной записи и считывать 40000001-ую)</p>
<p>Конечно, решение ограничено *nix системами, но т.к. моя система и без того использует pcntl_fork, она уже была привязана к никсам, так что хуже мне не стало.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

