<?xml version="1.0" encoding="koi8-r"?>
<rss version="0.91">
<channel>
    <title>OpenForum RSS: clone() и malloc()</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html</link>
    <description>Прошу помощи у знающих людей.&lt;br&gt;&lt;br&gt;Создаю процессы с помощью clone() с флагами: CLONE_VM &amp;#124; CLONE_FS &amp;#124; CLONE_FILES &amp;#124; CLONE_SIGHAND &amp;#124; SIGCHLD &amp;#124; CLONE_SYSVSEM.&lt;br&gt;Если добавить флаг CLONE_THREAD, то все работает нормально, но этот флаш не нужен.&lt;br&gt;&lt;br&gt;При этом когда они начиют конкурировать между собой, возникает deadlock в функциях malloc()/free()&lt;br&gt;&lt;br&gt;используется clone(), а не fork() потому что в приложении нужно шарить очень много данных.&lt;br&gt;используется clone(), а не pthread_create() потому что при смерти треда (seg fault) завершается сразу все приложение.&lt;br&gt;То есть хочется что бы и процессы между собой все делили, и при этом были независимы друг от друга в случае смерти.&lt;br&gt;В функциях glibc есть внутренние блокировки, непонятно только почему они заходят в deadlock.&lt;br&gt;&lt;br&gt;&lt;br&gt;Код для демонстрации:&lt;br&gt;&lt;br&gt;int func(void *p)&lt;br&gt;&#123;&lt;br&gt;while (1) &#123;&lt;br&gt;p = (char *)malloc(6);&lt;br&gt;memcpy(p, &quot;12345&#092;0&quot;, 5);&lt;br&gt;free(p);&lt;br&gt;&#125;&lt;br&gt;&#125;&lt;br&gt;&lt;br&gt;#define STACK_SIZE 1024*1024&lt;br&gt;&lt;br&gt;int main()&lt;br&gt;&#123;&lt;br&gt;int i;&lt;br&gt;                                    </description>

<item>
    <title>clone() и malloc() (pavlinux)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#20</link>
    <pubDate>Sun, 15 Jan 2012 10:50:54 GMT</pubDate>
    <description>&amp;gt;&amp;gt;&amp;gt;&#091;оверквотинг удален&#093; &lt;br&gt;&lt;br&gt;Короче не ..би моск&lt;br&gt;&#091;code&#093; &lt;br&gt;static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;&lt;br&gt;&lt;br&gt;int func(void *ptr) &#123;&lt;br&gt;&lt;br&gt;    char *msg = (char *) ptr;&lt;br&gt;&lt;br&gt;    while (1) &#123;&lt;br&gt;        pthread_mutex_lock(&amp;lock);&lt;br&gt;          msg = malloc( 6);&lt;br&gt;          strncpy(msg, &quot;12345&#092;0&quot;, 6);&lt;br&gt;          free(msg);&lt;br&gt;        pthread_mutex_unlock(&amp;lock);&lt;br&gt;    &#125;&lt;br&gt;    return 0;&lt;br&gt;&#125;&lt;br&gt;&#091;/code&#093; &lt;br&gt;&lt;br&gt;Кстати, размер стека лучше узнавать у getrlimit(RLIMIT_STACK, rlim) ...&lt;br&gt;</description>
</item>

<item>
    <title>clone() и malloc() (nikolayshm)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#19</link>
    <pubDate>Sun, 15 Jan 2012 00:08:31 GMT</pubDate>
    <description>&amp;gt;&amp;gt; При этом когда они начиют конкурировать между собой, возникает deadlock в функциях &lt;br&gt;&amp;gt;&amp;gt; malloc()/free() &lt;br&gt;&amp;gt; Конечно возникает. Потому что память одного процесса неожиданно редактирует другой процесс. &lt;br&gt;&lt;br&gt;Так вопрос-то был соответствующий - почему так. malloc/free они ведь thread-safe :)&lt;br&gt;&lt;br&gt;&amp;gt; Если какой-то поток вызывает SIGSEGV - значит вся память испорчена. Общая, всего &lt;br&gt;&amp;gt; процесса!!&lt;br&gt;&lt;br&gt;Кстати, это неправильное утверждение.&lt;br&gt;SIGSEGV is the signal sent to a process when it makes an invalid memory reference, or segmentation fault.&lt;br&gt;</description>
</item>

<item>
    <title>clone() и malloc() (nikolayshm)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#18</link>
    <pubDate>Sun, 15 Jan 2012 00:02:45 GMT</pubDate>
    <description>&amp;gt;&amp;gt;&#091;оверквотинг удален&#093; &lt;br&gt;&amp;gt;&amp;gt; В переводе это означает что передавать нужно ссылку на память, &lt;br&gt;&amp;gt;&amp;gt; а не ссылку на ссылку на память.&lt;br&gt;&amp;gt; Чуток не правильно понимаешь свойства работы с указателем на указатель.&lt;br&gt;&amp;gt; Ну на, в твоем виде &lt;br&gt;&lt;br&gt;С Вашего позволения, тоже перейду на &quot;ты&quot;.&lt;br&gt;&lt;br&gt;Объясни, мне пожалуйста, что я неправильно понимаю. Можно ссылкой в ман, гугл или куда угодно.&lt;br&gt;&lt;br&gt;Что касается кода, правильно ли я понял фразу &quot;Ну на, в твоем виде&quot; - означает, что 2 кода которые ты привел они идентичны, только &quot;вид&quot; разный?&lt;br&gt;Для наглядности:&lt;br&gt;&lt;br&gt;первый:&lt;br&gt;&lt;br&gt;&#091;code&#093; &lt;br&gt;    void **stack;&lt;br&gt;    for (i = 0; i &amp;lt; 10; i++) &#123;&lt;br&gt;         stack = (void **)malloc(STACK_SIZE);&lt;br&gt;         clone(func, stack, FLAGS, NULL);&lt;br&gt;    &#125;&lt;br&gt;&#091;/code&#093; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;второй:&lt;br&gt;&lt;br&gt;&#091;code&#093; &lt;br&gt;    void **stack;&lt;br&gt;    stack = malloc(STACK_SIZE);&lt;br&gt;    for (i = 0; i &amp;lt; 10; i++) &#123;&lt;br&gt;        *stack = (void *)(STACK_SIZE + (char *)stack);&lt;br&gt;        clone(func, stack, FLAGS, NULL);&lt;br&gt;    &#125;&lt;br&gt;&#091;/code&#093; &lt;br&gt;&lt;br&gt;</description>
</item>

<item>
    <title>clone() и malloc() (svn)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#17</link>
    <pubDate>Sat, 14 Jan 2012 23:19:01 GMT</pubDate>
    <description>&amp;gt; При этом когда они начиют конкурировать между собой, возникает deadlock в функциях &lt;br&gt;&amp;gt; malloc()/free() &lt;br&gt;&lt;br&gt;Конечно возникает. Потому что память одного процесса неожиданно редактирует другой процесс.&lt;br&gt;&lt;br&gt;Если какой-то поток вызывает SIGSEGV - значит вся память испорчена. Общая, всего процесса!!&lt;br&gt;Ничего хорошего в работе программы с испорченной памятью не может быть.&lt;br&gt;</description>
</item>

<item>
    <title>clone() и malloc() (pavlinux)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#16</link>
    <pubDate>Sat, 14 Jan 2012 20:59:35 GMT</pubDate>
    <description>&amp;gt;&#091;оверквотинг удален&#093;&lt;br&gt;&amp;gt; В переводе это означает что передавать нужно ссылку на память, &lt;br&gt;&amp;gt; а не ссылку на ссылку на память.&lt;br&gt;&lt;br&gt;Чуток не правильно понимаешь свойства работы с указателем на указатель.&lt;br&gt;Ну на, в твоем виде &lt;br&gt;&lt;br&gt;&#091;code&#093;&lt;br&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br&gt;#include &amp;lt;string.h&amp;gt;&lt;br&gt;#include &amp;lt;sched.h&amp;gt;&lt;br&gt;#include &amp;lt;signal.h&amp;gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;#define STACK_SIZE (1024*1024)&lt;br&gt;#define FLAGS (CLONE_VM&amp;#124;CLONE_FS&amp;#124;CLONE_FILES&amp;#124;CLONE_SIGHAND&amp;#124;CLONE_SYSVSEM&amp;#124;SIGCHLD)&lt;br&gt;&lt;br&gt;int func(void *p) &#123;&lt;br&gt;    &lt;br&gt;    while (1) &#123;&lt;br&gt;           p = (char *)malloc(6);&lt;br&gt;           memcpy(p, &quot;12345&#092;0&quot;, 6);&lt;br&gt;           free(p);&lt;br&gt;    &#125;&lt;br&gt;&#125;&lt;br&gt;&lt;br&gt;int main() &#123;&lt;br&gt;&lt;br&gt;    int i;&lt;br&gt;    void **stack;&lt;br&gt;    &lt;br&gt;    for (i = 0; i &amp;lt; 10; i++) &#123;&lt;br&gt;         stack = (void **)malloc(STACK_SIZE);&lt;br&gt;         clone(func, stack, FLAGS, NULL);&lt;br&gt;    &#125;&lt;br&gt;&lt;br&gt;    sleep(10);&lt;br&gt;    return 0;&lt;br&gt;&#125;&lt;br&gt;&#091;/code&#093;&lt;br&gt;</description>
</item>

<item>
    <title>clone() и malloc() (nikolayshm)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#15</link>
    <pubDate>Sat, 14 Jan 2012 16:04:17 GMT</pubDate>
    <description>&amp;gt; Блин, вы С учить будете? А то glibc, треды... придумали тоже... :) &lt;br&gt;&lt;br&gt;Буду рад, если Вы подскажите что почитать для получения новых знаний. &lt;br&gt;&lt;br&gt;&amp;gt; У Вас указатель *stack ВСЕ ВРЕМЯ указывает на один и тот же &lt;br&gt;&amp;gt; сегмент, &lt;br&gt;&amp;gt; над которым затем трахаются по 10 копий malloc и free!!!&lt;br&gt;&lt;br&gt;Мой код:&lt;br&gt;for (i=0; i&amp;lt;10; i++) &#123;&lt;br&gt;        void *stack = malloc(STACK_SIZE);&lt;br&gt;&#125;&lt;br&gt;&lt;br&gt;переменной stack присывается новое значение, так что *stack никак не может указывать на одинаковый сегмент памяти.&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;gt; Ниже я показал, что надо юзать указатель на указатель (можно массив указателей) &lt;br&gt;&lt;br&gt;Кусок Вашего кода:&lt;br&gt;&lt;br&gt;stack = malloc(STACK_SIZE);&lt;br&gt;for (i = 0; i &amp;lt; 10; i++) &#123;&lt;br&gt;   *stack = (void *)(STACK_SIZE + (char *)stack);&lt;br&gt;   clone(func, stack, FLAGS, NULL);&lt;br&gt;&lt;br&gt;Вы выделили память размером STACK_SIZE,&lt;br&gt;затем в первый байт записали ссылку на конец выделенной памяти&lt;br&gt;передали в clone ссылку на выделенную память.&lt;br&gt;&lt;br&gt;У доке четко написано:&lt;br&gt;The child_stack argument specifies the location of the stack used by the child process. ... The calling pr</description>
</item>

<item>
    <title>clone() и malloc() (pavlinux)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#13</link>
    <pubDate>Sat, 14 Jan 2012 14:49:19 GMT</pubDate>
    <description>Блин, вы С учить будете? А то glibc, треды... придумали тоже... :)&lt;br&gt;&lt;br&gt;У Вас указатель *stack ВСЕ ВРЕМЯ указывает на один и тот же сегмент,&lt;br&gt;над которым затем трахаются по 10 копий malloc и free!!! &lt;br&gt;Да, на уровне ядра есть блокировки, собственно благодаря которым вы и получаете SIGSEGV,&lt;br&gt;а не смерть всего компа.&lt;br&gt;&lt;br&gt;Ниже я показал, что надо юзать указатель на указатель (можно массив указателей)&lt;br&gt; &lt;br&gt;&lt;br&gt;</description>
</item>

<item>
    <title>clone() и malloc() (nikolayshm)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#12</link>
    <pubDate>Wed, 11 Jan 2012 20:29:51 GMT</pubDate>
    <description>&amp;gt; незачто и судя по-тому, что вы хотели clone() &quot;потому что при смерти &lt;br&gt;&amp;gt; треда (seg fault) завершается сразу все приложение.&quot; - вы еще не &lt;br&gt;&amp;gt; пробовали посылать sigsegv ни одному из ваших &quot;работающих&quot; клонов. SIGSEGV, кстати, &lt;br&gt;&amp;gt; маскируется и обрабатывается.&lt;br&gt;&lt;br&gt;Этот момент я хорошо тестировал. SIGSEGV вызывал разными способами.&lt;br&gt;В случае с клонами (с указанными флагами) SIGSEGV ловится слоном, вызывается exit() и клон умирает. Родитель обрабатывает waitpid и продолжает работать.&lt;br&gt;В случае с тредами (pthread_create или флаг CLONE_THREAD) SIGSEGV тоже ловится, но ловит его родитель и продолжать работать не может. Умирает родитель и умирают все поражденные треды.&lt;br&gt;</description>
</item>

<item>
    <title>clone() и malloc() (me)</title>
    <link>https://slinkov.ru/openforum/vsluhforumID9/9352.html#11</link>
    <pubDate>Wed, 11 Jan 2012 19:11:42 GMT</pubDate>
    <description>&amp;gt;&#091;оверквотинг удален&#093;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; подумал. Но тот же pthread_create тоже использует CLONE_VM и проблем никаких.&lt;br&gt;&amp;gt;&amp;gt; так вы-ж его не иначе с -pthread собираете? :) &lt;br&gt;&amp;gt;&amp;gt;&amp;gt; Да и malloc использует внутреннюю блокировку, что бы быть thread-safe, &lt;br&gt;&amp;gt;&amp;gt; без флага pthread? или с флагом но без pthread_create? серьезно? :) &lt;br&gt;&amp;gt; Я собирал и без -pthread и с ней. добавлял -D_REENTRANT - все &lt;br&gt;&amp;gt; без результатно.&lt;br&gt;&amp;gt; но... по вашему &quot;намеку&quot; попробовал добавить в код pthread_create(), который создает тред &lt;br&gt;&amp;gt; и сразу его закрывает. все заработало.&lt;br&gt;&amp;gt; Очевидно что pthread_create что то проинициализировал. Я смотрел его код, но инициализацией &lt;br&gt;&amp;gt; связанных с памятью или локами не нашел (кроме стека).&lt;br&gt;&lt;br&gt;не, я имел ввиду pthread_create для создания потока вместо clone. Вы показали ваш собственный фокус. (весьма занятный, кстати. но я-бы не рассчитывал, что этот код будет работать всегда)&lt;br&gt;&lt;br&gt;&amp;gt; Спасибо Вам за помощь.&lt;br&gt;&lt;br&gt;незачто и судя по-тому, что вы хотели clone() &quot;потому что при смерти треда (seg fault) завершается сразу все приложение.</description>
</item>

</channel>
</rss>
