LINUX.ORG.RU

межпроцесные коммуникации в linux


0

0

Необходимо выбрать способ межпроцессных соединений. Время крайне критично. Сделал тест для named pipe, shared memory, socket(PF_LOCAL), message queue. Пишу/читаю 1000В, замеряю время. Система MontaVista Linux. Поидее быстрее всех должна быть shared memory. Но получил такие результаты: shared memory - 22 message queue - 11 named pipe - 10 socket - 62 врямя(сумарное чтения и записи) дано в микросекундах. Вопрос: почему shared memory работает медленее чем message queue и named pipe? так ли должно быть?

anonymous

А поточнее нельзя - как конкретно время меряешь?

И какую shared memory пользовал - mmap или SYSV ?

Die-Hard ★★★★★
()

Как можно сравнивать "производительность" прокачки данных по каналам и общей памяти, если первое - это синхронный обмен, а второе - асинхронный?

Понятно что если ты забьешь буфер канала то произойдет переключение на читателя. В случае с общей памятью переключение будет происходить только когда процесс съест весь свой квант ...

Короче, ты что-то непонятное меряешь. ;)

Murr ★★
()
Ответ на: комментарий от Die-Hard

Использую SZSV. мерею с помощью gettimeofday время работы memcpy(в случае shared memory) msgsnd, msgrcv(в случае message queue) read, write(в случае socket and named pipe) , на клиенте записи, на сервере чтения.

anonymous
()
Ответ на: комментарий от Murr

в общем согласен. Но ситуация такая: server создает семафор и переходит в его ожидание. Далее client пищет в память и устанавливает семафор, server разблакируется и читает из памяти.

anonymous
()

Как правило разделяемая память проигрывает.
pipe обычно выигрывает, в некоторых unix может выигрывать socket.

io ★★
()
Ответ на: комментарий от anonymous

Такая схема ничем не отличается от принципа действия pipe кроме двух лишних копирований в pipe, поэтому разделяемая память _очевидно_ лучше. ;) Кроме того, у pipe в Linux (2.4 как минимум) ограничение буфера в 1 страницу, поэтому передача крупных кусков данных вообще пролетает ...

Давайте тесты - будем смотреть.

Murr ★★
()

Все определяется использованием.
shared лучше именно для совместного использования.
Типа буферов БД.
На малых объемах сравнивать особо нечего.
Все может сожрать организация соединения.
В случае же массовой прокачки через память возможны потери,
а не выигрыш.
Синхронизация она тоже кушать хочет.
Но источники посмотреть полезно.

io ★★
()
Ответ на: комментарий от Murr

А зачем, если они уже часть ядра. Ей бо дешевле.
В самом ядре часто вещи происходят без какой-либо формальной
синхронизации. Попробуйте на уровне задачи и в ядре на одном процессоре выполнить тривиальное, но гарантированное увеличение переменной, например, на 1 для многонитевой задачи.
Будет "почти работать". Я наблюдал как тупое ("тривиальное") решение
именно подобной задачи с переменной в shared memory давало
сбой раз в 10-30 минут (а это было число переданных сообщений).
Иногда это не важно.
А в ядре atomic и усе.
Но это только часть туфты, shared memory требует и других ресурсов.

io ★★
()
Ответ на: комментарий от io

LOCK на Intel начиная с 386 (на 286 вроде нельзя) можно делать и в userspace. ;)

IMHO, как напишешь - так и будет.

То есть я без проблем могу накатать тест, где обмен данными через shared memory будет в разы быстрее, чем через pipe, просто не вижу смысла.

Единственный более-менее реальный бонус pipe - это простота использования.

Murr ★★
()
Ответ на: комментарий от Murr

Я как всегда забыл, что на свете есть только 386 процессор :-(
Надо было предложить какую-нибудь списковую операцию (это атомарно
не все умеют) или что-то чуть круче.
Для ядра почти без разницы, а для userspace она накопится.

А написать тест рекомендую попробовать.
Предположим есть желание обмениваться пакетами размером 20-10000 байт.
Например сымитировать dd if= | dd of=, но не с фиксрованным буфером а с хаотичым распределением по длине.
Так будет забавнее, т.к. "накатать тест", который доказывает что-то конкретное всегда легко.
А поэкспериментировать и посмотреть на реальное поведение достаточно сложно.
К сожалению, все еще зависит от приложения.
Чистый тест достаточно туп.
Я точен и знаю что реализация обмена через shared memory может
(может!), но вовсе не обязана быть быстрее.
Сам делал, сам скорость выжимал, сам на грабли наступал.
Давно правда. Но просто так не обязана!
А уж получить разницу в разы - почти дудки.

io ★★
()
Ответ на: комментарий от io

>Я как всегда забыл, что на свете есть только 386 процессор :-( >Надо было предложить какую-нибудь списковую операцию (это атомарно >не все умеют) или что-то чуть круче. >Для ядра почти без разницы, а для userspace она накопится.

А для какого процессора под Linux нет atomic операций в userspace? i386 я как пример привел.

По поводу pipe vs. shm

pipe: (+) не нужно входить в ядро и выходить из ядра на синхронизации (-) нужна частая ресинхронизация при частых или объемных пересылках, т.к. буфер трубы быстро забивается (+) буфер после синхронной пересылки можно сразу использовать

shm: (+) не нужно ни одного лишнего копирования данных (+) более гибкие возможности для синхронизации (нет необходимости как в pipe во время пересылки данных обоим процессам торчать в ядре до завершения) как следствие предыдущего пункта

В общем, это разные механизмы и сравнивать их нет абсолютно никакого смысла. Разве что реализации для решения конкретных задач.

P.S. А в разы разница получится, если объем пересылаемых данных - не килобайты, а мегабайты. Данные из процесса в процесс копируются не мгновенно, тем более, что два раза и с постоянными переключениями.

P.P.S. Всё IMHO, разумеется.

Murr ★★
()
Ответ на: комментарий от Murr

2Murr (*) (21.12.2003 18:47:45):

> Данные из процесса в процесс копируются не мгновенно, тем более, что два раза и с постоянными переключениями.

Не въехал... Поясни, pls...

Die-Hard ★★★★★
()
Ответ на: комментарий от Murr

Ну не читал человек книжек по параллельному программированию.
Потому и проблемы. Он и десять раз насчитает.
А все лень. Я вот просто наивный экспериментатор.
Мне было лениво вылизывать и делать приличную оптимизацию и
для shared и для pipe, но предварительные результаты такие:
Единообразная обработка данных в рамках процессов:
работа с разделяемой памятью выгоднее на 8% (хочу разы :-(
так как нет переписывания и принимающий процесс обрабатывает
данные прямо в разделяемой памяти.
Прокачка больших объемов (аналог dd) работа с пайпами выгоднее на 5%.
Правда на одной программе у меня пайпы оказались в два раза лучше,
это исправилось :-), но пришлось попотеть, сейчас память на 3% лучше,
но код омерзителен.

Эй, Murr хочу разы. БД не предлагать. Хотя даже некоторые БД
shared memory не использует. И с чего бы это?

io ★★
()
Ответ на: комментарий от Die-Hard

Die-Hard:

>Не въехал... Поясни, pls...
Два - это копирование из процесса в ядра, а затем - из ядра в процесс.
Когда либо пишущий забивает буфер, либо читающий все считывает - происходят переключения (плюс они могу происходить сами по себе).

Просто io наивно полагает, что контексты переключаются мгновенно и память копируется тоже мгновенно, что вообще говоря слабо соответствует действительности ...

Murr ★★
()
Ответ на: комментарий от Murr

Вот код:

#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>

#define KB 1024
#define MB 1024*KB

#define SIZE 60*MB

void dummy (int sig) {
}

int main() {
    char* c = mmap (0, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
    char* cond = c+SIZE-1;
    int i, status, rc;
    long t;

    rc = fork ();

    t = clock ();
    signal (SIGUSR1, dummy);

    if (rc != 0) {
        for (i=0; i<SIZE-1; i++)
            c[i] = (char)i;

        *cond = 1; kill (rc, SIGUSR1);

        wait (&status);
        printf ("it took me %f\n", ((double)(clock()-t))/CLOCKS_PER_SEC);
    }
    else {
        long long s = 0;

        while (*cond == 0) pause();

        for (i=0; i<SIZE-1; i++)
            s += c[i];

        return 0;
    }

    return 0;
}

#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>

#define KB 1024
#define MB 1024*KB

#define SIZE 60*MB

int main() {
    char* c = (char*)malloc(SIZE);
    char* cond = c+SIZE-1;
    int i, status, rc;
    long t;
    int fd[2];

    pipe(fd);

    rc = fork ();

    t = clock ();

    if (rc != 0) {
        for (i=0; i<SIZE-1; i++)
            c[i] = (char)i;

        write (fd[1], c, SIZE);

        wait (&status);
        printf ("it took me %f\n", ((double)(clock()-t))/CLOCKS_PER_SEC);
    }
    else {
        long long s = 0;

        read (fd[0], c, SIZE);

        for (i=0; i<SIZE-1; i++)
            s += c[i];

        return 0;
    }

    return 0;
}

Murr ★★
()
Ответ на: комментарий от Murr

Прежде, чем посылать проверять надоть !
И где обещанные мне разы на программе, которая специально
оптимизировалась для shared memory?
Результат не стабилен, ускорение в пределах 0-12%.
Рекомедую попробовать на объемах, когда результат более стабилен,
вариант с 3% я проверял на 3 Гб.
Да, батенька, да на реальной задаче с пакетами не в 60Мб,
а что-то в килах или менее, вам даже моих стабильных 8% не поиметь
(пойти запатентовать алгоритм что ли?):

$ ./rmem
it took me 0.510000
$ ./rpipe
it took me 0.510000
$ time ./rmem
it took me 0.500000

real 0m1.408s
user 0m1.250s
sys 0m0.160s
$ time ./rpipe
it took me 0.560000

real 0m1.638s
user 0m1.190s
sys 0m0.450s

io ★★
()
Ответ на: комментарий от io

io:

>Прежде, чем посылать проверять надоть ! 
Было бы странно, если бы я не догадался ...

>И где обещанные мне разы на программе, которая специально 
оптимизировалась для shared memory? 
Я Вам ничего не обещал. И уж чем не занимался - так "оптимизацией" чего либо. Я привел абсолютно прозрачный пример, который дает на моей конфигурации разницу в 1.5 раза. Если приводить какой-либо специальный пример, то будет поболе.

На моем пример с пакетом в 100 Мб:

[root@censored tests]# make mmap; make pipe
cc     mmap.c   -o mmap
cc     pipe.c   -o pipe
[root@censored tests]# ./mmap
it took me 3.110000
[root@censored tests]# ./pipe
it took me 4.560000
[root@censored tests]#

>Результат не стабилен, ускорение в пределах 0-12%. 

Результат в таком тесте и не может быть стабилен. И у меня колеблется в пределах 1.5-1.8 в пользу mmap.

>Рекомедую попробовать на объемах, когда результат более стабилен, 
вариант с 3% я проверял на 3 Гб.

Ну сказки можете рассказывать какие угодно, но я немного представляю как вся эта байда работает. 3% - это какой-то совсем жидкий прогон.

Возьмите исходники ядра и прибросьте сколько вы лишней памяти копируете в трубах и сколько контекстных переключений при этом происходит.
 
>Да, батенька, да на реальной задаче с пакетами не в 60Мб, а что-то в килах или менее, вам даже моих стабильных 8% не поиметь (пойти запатентовать алгоритм что ли?)

Лучше книжку почитайте... исходники пока рано...

Murr ★★
()
Ответ на: комментарий от Murr

Поставь mlockall, чтобы у тебя I/O меньше влияло на времена.

Murr ★★
()
Ответ на: комментарий от Murr

То-то у Вас батенька проблемы с чтением bfd возникли.
А книжку я почитаю, свою сотню страниц в день обязательно,
чукча не должен быть только писатель, чукча должен быть и читатель.

Судя по скорсти прогон был точно на 386.
Тогда верю, результат будет именно такой.
Тут уж дело даже не в том, как ОС работает, а в том, что памяти
заказано столько, что своп содрагнется. 100 Mb пакет это хорошо.
Рекомендую увеличить пакет до размера в 2 памяти, точно обскачет.
Но мне были обещаны разы, а не 80%. Все это к рельности не
имеет никакого отношения. Так тесты не пишут, это именно оптимизация
под разделяемую память для нереальных условий. Нельзя даже сдать
как лабу приличному преподу.

К сожалению, последние n лет у меня задач меньше, чем на сотни Мб почти нет.
Поэтому проверял именно на реальной задаче, которая именно
гигобайты и пережевывает.
Живет на любой разумной платформе, в частности, Linux,
и Windows, а если надо, то и кусками на разнотипных.
Дабы было совсем ясно делает это в интерактиве и платят только
за интерактив.
Сказки можно читать себе на ночь сами.


io ★★
()
Ответ на: комментарий от io

io:
>То-то у Вас батенька проблемы с чтением bfd возникли.
А у Вас не возникло? На пару вопросиков готовы ответить в интерактиве?
Тогда что же не ответили в моей теме?

>Судя по скорсти прогон был точно на 386.
>Тогда верю, результат будет именно такой.
>Тут уж дело даже не в том, как ОС работает, а в том, что памяти
>заказано столько, что своп содрагнется. 100 Mb пакет это хорошо.
>Рекомендую увеличить пакет до размера в 2 памяти, точно обскачет.
>Но мне были обещаны разы, а не 80%. Все это к рельности не
>имеет никакого отношения. Так тесты не пишут, это именно оптимизация
>под разделяемую память для нереальных условий. Нельзя даже сдать
>как лабу приличному преподу.
Ну и причем тут 386, мистер всезнайка? Что-то Вы мне активно свой широкий кругозор архитектур демонстрируете, а с atomic лажанулись как ребенок... Видать даже примерно не представляете как per-thread синхронизация сделана в LinuxThreads... да-да-да есть там spin блокировки. ;)

100 Мб пакет был выбран так, чтобы 2*100 Мб целиком влезло в память.

По поводу маленьких пакетов - на них в данном тесте будет выигрыш за счет отсутствия cache thrashing, причем тоже ощутимый. То, что pipe будет хоть где-то быстрее - это полный пурген. Да, mmap быстрее не в 2, а в полтора раза, тут я был не прав в оценке чистого времени копирования, но суть остается той же. В реальной задаче даже меньше (а разы я обещал именно в идеальном для mmap случае, который я тут не приводил).

Тем не менее, при грамотном обращении с mmap, pipe _никогда_ не будет быстрее (собственно меня обратное утверждение автора темы и смутило).

По поводу СУБД - не привели бы Вы пример где front-end СУБД с ядром общается через pipe? А то я (наверное, в виду своей ограниченности, знаком с реализациями _чистой_ shared memory - например, Informix).

Murr ★★
()
Ответ на: комментарий от Murr

Ну хоть первое согласие, что в оценке лажанулся получил.

Я не считаю себя всезнайкой и всегда готов признать ошибку,
хотя и обязательно все проверю, т.к. на словах пургу все гонят.
А то что во всех Linux есть atomic на уровне thread это точно пурга,
т.к. определяется весьма специфичными возможностями архитектуры,
а она ой какая разная.
Сверху же явно написано Monta Vista. Что сие означает?
Что не было этой версии Linux скорее у Вас батенька, а у меня была.

Имею нахальство утверждать, что и с маленькими пакетами не все чисто
и тоже с оценкой следовало бы повременить и попробовать на больших
объемах. А в Вашем тесте батенька один только пакетик и есть.

Проблема в том, что грамотное обращение с mmap это очень скользкий
предмет. Мы ведь даже не перешли к многопроцессорным архитектурам,
а там большие грабли с этим. Но даже на однопроцессорной машине
есть где повозиться чтобы получить реальное существенное ускорение
(за счет потери гибкости).

Теория параллельных вычислений говорит о том, что синхронный
(я надеюсь ясно что работа с mmap это синхронная обработка) процесс
обработки (как и любое синхронное взаимодействие) в принципе
может приводить к дополнительным потерям (сейчас какие-то "основы
параллельных вычислений ..." выпустили, рекомендую посмотреть).
В некоторых случаях категорически рекомендуется вводить третий
буферизующий ассинхронный процесс для уменьшения возникающих проблем.
Все исключительно определяется приложением. Да обычно удается
ускорится за счет памяти, я готов признать, что это достижимо "в
нормальной жизни" более, чем в 80% случаях, но то, что это верно
всегда тоже пурга.

Уже собственный пример должен был показать, что не все очевидное
на самом деле очевидно. А на пример сверху вообще не стоило обращать
внимание, не тот объем для теста. Он же только время инициализации и
померял - это же фуфел.

Вообще хавать столько памяти через mmap дурной тон.
Оптимизация - процесс тонкий. Уменьшение памяти в два раза
"при грамотном обращении" эквивалентно ускорению в 5 раз.

Informix я знаю, сам источники смотрел, хорошо штука написана,
не спорю. Правда, тоже иногда мимо буфера данные пускает - быстрее.
А БД на pipe-ах в opensource есть, где-то даже на форумах упоминалась.


io ★★
()
Ответ на: комментарий от io

2io (*) (22.12.2003 20:16:48):

Т.е., ты продолжаешь утверждать, что на реальных задачах шареная память проигрывает трубкам?

Ты это серьезно?

2Murr: thanks.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Вот и пиши после этого :-)
Мне казалось я уже все очень точно написал.
Не надо вешать на меня лишние ярлыки.
Я таки люблю точные формулировки:
Факт 1: В хороших руках shared memory _обычно_ позволяет получить
лучшую производительность.
Факт 2: Использование shared memory именно в стиле односторонней
передачи данных, как всякое синхронное действие, может
быть недостаточно эффективно. При плохом программировании
(а я имел возможность сравнивать) среднестатистический
программист может получить произвольное соотношение
с трубками (т.е. и больше, и меньше).
Факт 3: Трубки обеспечивают большую гибкость в решениях. В связи со 2
пунктом я почти всегда советую использовать трубки. Перейти
от них к памяти всегда проще, чем сделать обратное. Сам
всегда стараюсь быть независимым от транспорта.
Факт 4: Если производится обработка данных от большого количества
источников, то нужен очень хороший анализ перед выбором
представления, трубки можно выбирать всегда (см. 3).
Факт 5: На свете существуют другие операционные системы. Механизм
посылки сообщений есть всегда. Приличное управление
приоритетами не обязательно. Встречал операционные системы,
где передача сообщений эффективнее в несколько раз, иногда
бывает наоборот аналогично в разы.
Факт 6: Есть часть алгоритмов, которые удивительно хорошо работают
именно для конвейерной организации жизни при многопроцессорной
работе, на одном процессоре выбор почти безразличен (см. 1).

io ★★
()

Слушай, да... У меня вопрос больше о MontaVista... Вы ее покупали? Где, по чем? С какой бордой работаете при этом?

Мы попробовали на русском Fastwel-е свой дистрибутив склепать -- чуть не умерли. Флешки через одно место работают, с сетью правда проблем не было, графику на ней поднимать мне страшно... %-)

tarle
()
Ответ на: комментарий от tarle

Борда с MIPS кажется от NEC, работа для самой MV.
Борда от Intel (что-то типа XScale PXA25...
точный номер не скажу - склероз:), работа для самой MV.
Т.ч. не покупали.
В Москве сейчас есть как минимум одна команда,
кажется, в RTSoft, которая работает для MV,
попробуйте узнать цену у них.

io ★★
()

это опять автор темы. 1. Тесты естественно делаются не один раз а 1000 так что о измерении времени инициализации речь не идет. Исходники показать сейчас не могу(моя Linux мащина(а исходниеки на ней) сейчас не дееспособна). Работаю на компани IskraTel. Пишу на OS WxWorks, PsOS. Ceйчас частично переходим на Linux, так что пока понятно в Linux я не особо силен. Моя задача была такова: на VxWorks была DBMS собственной разработки. Деления на client and server не было (только hard-link). DBMS работает жестко (т.е. ес препроцессинг). Перенес на Linux. Разделил на client server используя сокет для "обшения" client server. Но 80 - 90 % времени уходит на "общение". Передаваемые сообщ невелеки (50B - 100, редко 1000B). Понятно что на телефонной станции скажем в 50000 номеров в ЧНН количество обращений к БД на switche Может достигать 100000 в минуту + синхронизация с Manegment node. Поэтому необходимо уменьщить время пересылки. Да есче вопрос как Linux для потока созданного в режиме realtime(в коде исчи DBMS_REAL_TIME_MODE) считает линейку квантов и велечину самого кванта? .логика данного кода своеобразно но это связоно с другими кусками написынными не мной ... struct THREAD { pthread_t pthread_id; char* pthread_name; struct THREAD* pthread_next; struct THREAD* pthread_prev; };

struct ARG_FUNC { int (*func)(); char* name; int arg1; int arg2; int arg3; int arg4; int arg5; int arg6; int arg7; int arg8; int arg9; int arg10; };

...

anonymous
()
Ответ на: комментарий от anonymous

int taskSpawn (char *name, int priority, int options, int stackSize, FUNCPTR entryPt, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10) { int rv, min_pr, max_pr, lin_pr; struct ARG_FUNC* arg_func; struct THREAD* currentthread; pthread_attr_t attr; struct sched_param sch_pr;

//count linux priorytet min_pr = sched_get_priority_min(SCHED_FIFO); max_pr = sched_get_priority_max(SCHED_FIFO);

lin_pr = max_pr - ((float)(max_pr - min_pr + 1))/((float)(MIN_VX_WORKS_PR - MAX_VX_WORKS_PR + 1))*priority; if(lin_pr < min_pr) sch_pr.sched_priority = min_pr; else if(lin_pr > max_pr) sch_pr.sched_priority = max_pr; else sch_pr.sched_priority = lin_pr;

//init thread atrybuts rv = pthread_attr_init(&attr); if(rv != 0) { return ERROR; } rv = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); if(rv != 0) { return ERROR; } rv = pthread_attr_setschedparam(&attr, &sch_pr); if(rv != 0) { return ERROR; }

//start critycal section pthread_mutex_lock(&task_mutex);

arg_func = malloc(sizeof(struct ARG_FUNC));

if(pthread == NULL) { pthread = malloc(sizeof(struct THREAD)); if(pthread == NULL) { pthread_mutex_unlock(&task_mutex); return ERROR; }

pthread->pthread_name = NULL; pthread->pthread_name = malloc(strlen(name)+1); if(pthread->pthread_name == NULL) { pthread_mutex_unlock(&task_mutex); return ERROR; }

strcpy(pthread->pthread_name, name);

arg_func->func = entryPt; arg_func->name = malloc(strlen(name) + 1); strcpy(arg_func->name, name);

#ifdef DBMS_REAL_TIME_MODE /*create thread*/ rv = pthread_create(&(pthread->pthread_id), &attr, pthread_func, arg_func); #else /*create thread*/ rv = pthread_create(&(pthread->pthread_id), NULL, pthread_func, arg_func); #endif if(rv == EPERM) { pthread_mutex_unlock(&task_mutex); E("ERROR:The caller does not have appropriate permission to set the required scheduling parameters or scheduling policy\n"); return ERROR; } else if(rv != 0) { pthread_mutex_unlock(&task_mutex); return ERROR; }

pthread_attr_destroy(&attr);

rv = ui_numthread++;

pthread_last = pthread; pthread->pthread_prev = NULL;

pthread_mutex_unlock(&task_mutex);

return rv; }

anonymous
()
Ответ на: комментарий от anonymous

currentthread = pthread_last; currentthread->pthread_next = malloc(sizeof(struct THREAD)); if(currentthread->pthread_next == NULL) { pthread_mutex_unlock(&task_mutex); return ERROR; }

currentthread = currentthread->pthread_next;

currentthread->pthread_name = NULL; currentthread->pthread_name = malloc(strlen(name)); if(currentthread->pthread_name == NULL) { pthread_mutex_unlock(&task_mutex); return ERROR; }

strcpy(currentthread->pthread_name, name);

arg_func->func = entryPt; arg_func->name = malloc(strlen(name) + 1); strcpy(arg_func->name, name);

#ifdef DBMS_REAL_TIME_MODE /*create thread*/ rv = pthread_create(&(currentthread->pthread_id), &attr, pthread_func, arg_func);// use pthread_attr_setschedpolicy only as super user #else /*create thread*/ rv = pthread_create(&(currentthread->pthread_id), NULL, pthread_func, arg_func); #endif if(rv == EPERM) { pthread_mutex_unlock(&task_mutex); E("\nERROR:The caller does not have appropriate permission to set the required scheduling parameters or scheduling policy\n"); return ERROR; } else if(rv != 0) { pthread_mutex_unlock(&task_mutex); return ERROR; }

pthread_attr_destroy(&attr);

rv = ui_numthread++;

pthread->pthread_prev = pthread_last; pthread_last = currentthread;

pthread_mutex_unlock(&task_mutex);

return rv; }

...

void* pthread_func(void* arg) { int i; struct ARG_FUNC* parg = (struct ARG_FUNC*)arg; struct THREAD* copy = pthread;

retval = (*(parg->func))();

pthread_mutex_lock(&task_mutex);

for(i = 0; i < ui_numthread; i++) { if(0 == strcmp(parg->name, copy->pthread_name)) { if(copy->pthread_prev != NULL) (copy->pthread_prev)->pthread_next = copy->pthread_next; else pthread = pthread->pthread_next;

free(copy->pthread_name);

free(copy); ui_numthread--;

break; } copy = copy->pthread_next; }

pthread_mutex_unlock(&task_mutex);

free(parg);

return &retval; }

anonymous
()
Ответ на: комментарий от anonymous

Нельзя не отметить, что это более чем удачное форматирование текста:-)
Даже не очень ясно что закомментировано.
Это повтор или с одним именем, одной функцией и аргументами
стартует две задачи?
А где здесь формально передача данных?
Что есть имя? Нет ли уникальности?
Явный перебор по использованию mutex/malloc/free и т.п.
Сколько же задачек одновременно варится?
Могут быть проблемы с возвратом ресурсов.

io ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.