проблема с pthread
От: naje  
Дата: 08.09.03 18:39
Оценка:
что это может быть?:

Есть udp сервер, работает в виде (допустим) 4-х потоков, открытых в начале программы, один из них сокет который на каждый приём пакета передаёт данные в очередь из которой эту задачу забирают оставшиеся, с помощью pthread_cond...
Посылаю пачку из 100 запросов, первые три таких пачки проходят нормально, четвёртая, проходит с нереальными тормозами, все пачки запросов абсолютно одинаковые, смотрел в логах нигде нет не одного вызова lock уже залоченого мьютекса (он один), для pthread_cond.

Есть какие-то идеи?
Re: проблема с pthread
От: kiamor  
Дата: 09.09.03 05:00
Оценка:
Здравствуйте, naje.

N>Есть какие-то идеи?


Идеи есть поставь маленькую паузу в каждом
потоке (чувствую, они у тебя циклически работают ).
Посмотришь на результат. (Вместо паузы можно также
sched_yield вызвать).
Re[2]: проблема с pthread
От: naje  
Дата: 09.09.03 07:43
Оценка:
Здравствуйте, kiamor, Вы писали:

K>Здравствуйте, naje.


N>>Есть какие-то идеи?


K>Идеи есть поставь маленькую паузу в каждом

K>потоке (чувствую, они у тебя циклически работают ).
K>Посмотришь на результат. (Вместо паузы можно также
K>sched_yield вызвать).

А что значит циклически? Я заметил что они почему-то переключатся начинают как-то неправельно, т.б. слишком часто и в топе после того как всё отработалось этот процес ещё долго висит, я так понимаю это шедулер продолжает что-то делать. Один запрос выполняется в юзерспейсе где-то сотую секунды, полностью запрос с учётом запросов к базе где-то 3 десятые секунды, с учётом того что в юзерспейсе процесс выполняется мало получается что если запустить 10 потоков то 10 запросов будет выполнятся тоже приблизительно 3 десятые секунды, и это на практике работает, и для 20 и 30 потоков, т.б. 30 запросов за 3 десятые секунды, но потом что-то происходит, и какая-то след. пачка, выполняется медленнее чем если бы всё это обслуживал один поток (на один запрос бывает до секунды на 10 до 10 секунд), единственная синхронизация между потоками это pthread_cond.. с мьютексом, для обработки очереди запросов, больше не нужно. Если ставить sched_yield, то где? Там где ставятся задания в очередь или там где забираются?
Re[3]: проблема с pthread
От: kiamor  
Дата: 09.09.03 09:19
Оценка:
Здравствуйте, naje.

Циклически — значит периодически
Ну не один же раз поток вызывается. Я так понял, ты организовал
что-то вроде пула потоков, которым и пользуешься.

Теперича про sched_yield. Куда ее воткнуть — тебе виднее. Тут я,
как гритца, бессилен. Если код потока представляет собой цикл —
влепи в конец. Если код потока выполняется сначала до конца при
каждом обращении к потоку — тоже можешь влепить в конец. Однако
здесь прикинь время выполнения. Может и в середину неплохо будет.

Зачем ваще нужна ента самая фигня. Задержка, либо sched_yield,
нужна для того, чтобы пнуть планировщик и заставить его работать.
Надеюсь тебе известно, что из себя представляет библиотека pthread?
Та еще штучка. Этот самый бантик в сочетании с определенными задачами
поворачивается к программеру Ж. (Именно с большой буквы). Я с коллегами
наткнулся на один из таких приколов. Наш код вел себя так, как будто
линух вообще система с невытесняющей многозадачностью. Мы просто охренели.
Хотя казалось бы, пара процессов, в каждом по нескольку потоков. Ничего
страшного на первый взгляд не было. Единственное что спасло — периодический
пинок планировщику в коде каждого потока.
Re[4]: проблема с pthread
От: naje  
Дата: 09.09.03 12:43
Оценка:
Здравствуйте, kiamor, Вы писали:

K>Здравствуйте, naje.


K>Циклически — значит периодически

K>Ну не один же раз поток вызывается. Я так понял, ты организовал
K>что-то вроде пула потоков, которым и пользуешься.

K>Теперича про sched_yield. Куда ее воткнуть — тебе виднее. Тут я,

K>как гритца, бессилен. Если код потока представляет собой цикл -
K>влепи в конец. Если код потока выполняется сначала до конца при
K>каждом обращении к потоку — тоже можешь влепить в конец. Однако
K>здесь прикинь время выполнения. Может и в середину неплохо будет.

K>Зачем ваще нужна ента самая фигня. Задержка, либо sched_yield,

K>нужна для того, чтобы пнуть планировщик и заставить его работать.
K>Надеюсь тебе известно, что из себя представляет библиотека pthread?
K>Та еще штучка. Этот самый бантик в сочетании с определенными задачами
K>поворачивается к программеру Ж. (Именно с большой буквы).


Не помогло, похоже что Ж, начинаю переделывать в несколько процесов.
Re[5]: проблема с pthread
От: Аноним  
Дата: 09.09.03 13:23
Оценка:
Здравствуйте, naje, Вы писали:

N>Здравствуйте, kiamor, Вы писали:


K>>Здравствуйте, naje.


K>>Циклически — значит периодически

K>>Ну не один же раз поток вызывается. Я так понял, ты организовал
K>>что-то вроде пула потоков, которым и пользуешься.

K>>Теперича про sched_yield. Куда ее воткнуть — тебе виднее. Тут я,

K>>как гритца, бессилен. Если код потока представляет собой цикл -
K>>влепи в конец. Если код потока выполняется сначала до конца при
K>>каждом обращении к потоку — тоже можешь влепить в конец. Однако
K>>здесь прикинь время выполнения. Может и в середину неплохо будет.

K>>Зачем ваще нужна ента самая фигня. Задержка, либо sched_yield,

K>>нужна для того, чтобы пнуть планировщик и заставить его работать.
K>>Надеюсь тебе известно, что из себя представляет библиотека pthread?
K>>Та еще штучка. Этот самый бантик в сочетании с определенными задачами
K>>поворачивается к программеру Ж. (Именно с большой буквы).

IMHO sched_yield здесь не нужен — в idle time рабочие потоки должны висеть в wait() на pthread_cond,
а принимающий запросы поток на receive(), никаких циклов быть не должно.


N>Не помогло, похоже что Ж, начинаю переделывать в несколько процесов.


Ну зачем же так сразу сдаваться, или очень срочно надо сделать?
Посмотрел бы, какая загрузка проца, когда начинаются тормоза.
Если 100%, то кто её устраивает. Может БД решила заняться какими-то своими делами?
Если 0%, то в каком состоянии висит твой процесс и его thread'ы в это время.
Попробуй выводить в файл id thread'ов и время прохождения ими определённых точек и т.п.
А что будет, если запустить только 2 thread'а?
Re[6]: проблема с pthread
От: naje  
Дата: 09.09.03 14:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, naje, Вы писали:


N>>Здравствуйте, kiamor, Вы писали:


K>>>Здравствуйте, naje.


K>>>Циклически — значит периодически

K>>>Ну не один же раз поток вызывается. Я так понял, ты организовал
K>>>что-то вроде пула потоков, которым и пользуешься.

K>>>Теперича про sched_yield. Куда ее воткнуть — тебе виднее. Тут я,

K>>>как гритца, бессилен. Если код потока представляет собой цикл -
K>>>влепи в конец. Если код потока выполняется сначала до конца при
K>>>каждом обращении к потоку — тоже можешь влепить в конец. Однако
K>>>здесь прикинь время выполнения. Может и в середину неплохо будет.

K>>>Зачем ваще нужна ента самая фигня. Задержка, либо sched_yield,

K>>>нужна для того, чтобы пнуть планировщик и заставить его работать.
K>>>Надеюсь тебе известно, что из себя представляет библиотека pthread?
K>>>Та еще штучка. Этот самый бантик в сочетании с определенными задачами
K>>>поворачивается к программеру Ж. (Именно с большой буквы).

А>IMHO sched_yield здесь не нужен — в idle time рабочие потоки должны висеть в wait() на pthread_cond,

А>а принимающий запросы поток на receive(), никаких циклов быть не должно.

Отож, но в топе когда запросы прошли показывает что что-то ещё работает, причём конкретно работает.

N>>Не помогло, похоже что Ж, начинаю переделывать в несколько процесов.


А>Ну зачем же так сразу сдаваться, или очень срочно надо сделать?

А>Посмотрел бы, какая загрузка проца, когда начинаются тормоза.
А>Если 100%, то кто её устраивает. Может БД решила заняться какими-то своими делами?
А>Если 0%, то в каком состоянии висит твой процесс и его thread'ы в это время.
А>Попробуй выводить в файл id thread'ов и время прохождения ими определённых точек и т.п.
А>А что будет, если запустить только 2 thread'а?

Надо быстро сделать, но и разобратся очень сильно хочется.
С загрузкой всё нормально, никто ничево не делает.
Re[7]: проблема с pthread
От: Аноним  
Дата: 09.09.03 15:20
Оценка:
Здравствуйте, naje, Вы писали:

N>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, naje, Вы писали:


N>>>Здравствуйте, kiamor, Вы писали:


K>>>>Здравствуйте, naje.


K>>>>Циклически — значит периодически

K>>>>Ну не один же раз поток вызывается. Я так понял, ты организовал
K>>>>что-то вроде пула потоков, которым и пользуешься.

K>>>>Теперича про sched_yield. Куда ее воткнуть — тебе виднее. Тут я,

K>>>>как гритца, бессилен. Если код потока представляет собой цикл -
K>>>>влепи в конец. Если код потока выполняется сначала до конца при
K>>>>каждом обращении к потоку — тоже можешь влепить в конец. Однако
K>>>>здесь прикинь время выполнения. Может и в середину неплохо будет.

K>>>>Зачем ваще нужна ента самая фигня. Задержка, либо sched_yield,

K>>>>нужна для того, чтобы пнуть планировщик и заставить его работать.
K>>>>Надеюсь тебе известно, что из себя представляет библиотека pthread?
K>>>>Та еще штучка. Этот самый бантик в сочетании с определенными задачами
K>>>>поворачивается к программеру Ж. (Именно с большой буквы).

А>>IMHO sched_yield здесь не нужен — в idle time рабочие потоки должны висеть в wait() на pthread_cond,

А>>а принимающий запросы поток на receive(), никаких циклов быть не должно.

Предыдущий советчик имел ввиду, что в idle time, когда тебе делать нечего, ты бегаешь по циклу и кушаешь время (в том числе и то, которое могло бы достаться твоему другому thread'у, которому есть, что делать).

N>Отож, но в топе когда запросы прошли показывает что что-то ещё работает, причём конкретно работает.


Ну если ты не знаешь, кто, откуда же я знаю.

N>>>Не помогло, похоже что Ж, начинаю переделывать в несколько процесов.


А>>Ну зачем же так сразу сдаваться, или очень срочно надо сделать?

А>>Посмотрел бы, какая загрузка проца, когда начинаются тормоза.
А>>Если 100%, то кто её устраивает. Может БД решила заняться какими-то своими делами?
А>>Если 0%, то в каком состоянии висит твой процесс и его thread'ы в это время.
А>>Попробуй выводить в файл id thread'ов и время прохождения ими определённых точек и т.п.
А>>А что будет, если запустить только 2 thread'а?

N>Надо быстро сделать, но и разобратся очень сильно хочется.

N>С загрузкой всё нормально, никто ничево не делает.

тогда в каком состоянии висят thread'ы?
man ps, определить, висят они на mutex'е или на I/O точно можно.

можно в этот момент в наглую взять и приатачиться к процессу, поглядеть стек у thread'ов — в каком месте они висят.

// за правильность не ручаюсь, но идея, я думаю, ясна
#define TRACE printf("%u %ld %s:%u\n", get_thread_id(), time(NULL), __FILE__, __LINE__);

И расставляем эту радасть по файлам — до и после запросов к БД, до и после receive, pthread_cond_wait или как там её.
Время, конечно, лучше выбрать более точное, чем time(), но 10 секунд и так можно заметить.
Re[8]: проблема с pthread
От: naje  
Дата: 09.09.03 18:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>IMHO sched_yield здесь не нужен — в idle time рабочие потоки должны висеть в wait() на pthread_cond,

А>>>а принимающий запросы поток на receive(), никаких циклов быть не должно.

Ну и я ж про это, + те потоки которые в данный момент посылают к базе запросы тоже должны висеть на recv. Так и есть при первых пачках, т.б. когда запрос посылает один из потоков второй что-то делает. И т.д. блокировки во время выполнения запросов нет никакой (это по контрольным печатям).

N>>Отож, но в топе когда запросы прошли показывает что что-то ещё работает, причём конкретно работает.


А>Ну если ты не знаешь, кто, откуда же я знаю.


Вот в том то и дело что все потоки остоновились кто на cond_wait, кто на recv, а в это время почему то в топе что-то. И у меня только один подозреваемый — это шедулер.

А>тогда в каком состоянии висят thread'ы?

А>man ps, определить, висят они на mutex'е или на I/O точно можно.

У меня стандартная реализация FreeBSD там всё в юзер спейсе, ps ничево не даст.

А>можно в этот момент в наглую взять и приатачиться к процессу, поглядеть стек у thread'ов — в каком месте они висят.


А>// за правильность не ручаюсь, но идея, я думаю, ясна

А>#define TRACE printf("%u %ld %s:%u\n", get_thread_id(), time(NULL), __FILE__, __LINE__);

А>И расставляем эту радасть по файлам — до и после запросов к БД, до и после receive, pthread_cond_wait или как там её.

А>Время, конечно, лучше выбрать более точное, чем time(), но 10 секунд и так можно заметить.

Это всё делел, получил результаты которые выше вкратце описал. Единственное подозрительное заметил — это то что в неправильном случае потоки перестают переключатся во время выполнения запросов к базе (не ставить же для каждого запроса sched_yield). Но даже если бы всё и блокировалось на запросах всё-равно производительность выше должна получатся.
Re[9]: проблема с pthread
От: Аноним  
Дата: 10.09.03 07:31
Оценка:
N>Вот в том то и дело что все потоки остоновились кто на cond_wait, кто на recv, а в это время почему то в топе что-то. И у меня только один подозреваемый — это шедулер.

А что это что-то? у него наверное, есть pid и имя?
Может это lib'а доступа к БД запускает какой-нибудь свой thread?

N>Это всё делел, получил результаты которые выше вкратце описал. Единственное подозрительное заметил — это то что в неправильном случае потоки перестают переключатся во время выполнения запросов к базе (не ставить же для каждого запроса sched_yield). Но даже если бы всё и блокировалось на запросах всё-равно производительность выше должна получатся.


IMHO sched_yield не поможет, т.к. ты не можешь вызвать его ВОВРЕМЯ выполнения запроса к БД, т.е. либо ты вызываешь sched_yield() и она reshedule'ит thread'ы либо ты вызываешь ф-ию работы с БД и она делает то, что хочет (возможно, крутит циклы, но думаю, это не так — иначе загрузка была бы 100%).

Может у тебя один connect к БД на всех и они на нём блокируются?
Re[10]: проблема с pthread
От: naje  
Дата: 10.09.03 08:58
Оценка:
Здравствуйте, Аноним, Вы писали:

N>>Вот в том то и дело что все потоки остоновились кто на cond_wait, кто на recv, а в это время почему то в топе что-то. И у меня только один подозреваемый — это шедулер.


А>А что это что-то? у него наверное, есть pid и имя?


Мой процесс в топе вверху что-то делает хотя все потоки остоновлены.

А>Может это lib'а доступа к БД запускает какой-нибудь свой thread?


Это libpq для PostreSql, раньше такого за ней не замечал.

N>>Это всё делел, получил результаты которые выше вкратце описал. Единственное подозрительное заметил — это то что в неправильном случае потоки перестают переключатся во время выполнения запросов к базе (не ставить же для каждого запроса sched_yield). Но даже если бы всё и блокировалось на запросах всё-равно производительность выше должна получатся.


А>IMHO sched_yield не поможет, т.к. ты не можешь вызвать его ВОВРЕМЯ выполнения запроса к БД, т.е. либо ты вызываешь sched_yield() и она reshedule'ит thread'ы либо ты вызываешь ф-ию работы с БД и она делает то, что хочет (возможно, крутит циклы, но думаю, это не так — иначе загрузка была бы 100%).


Может помочь но извращатся нужно конкретно, я это и имел ввиду, например запустить его асинхронно, ну а потом......

А>Может у тебя один connect к БД на всех и они на нём блокируются?


Нет не один, libpq в таких случаях вобще падает, конекты по одному на поток, открываются в начале работы программы.
Re[11]: проблема с pthread
От: RXL  
Дата: 11.09.03 07:35
Оценка:
Посмотри в доке к базе — что там сказано про работу в многопоточной среде. Напр. в mysql нужно вызывать из каждого потока ф-ию инициализации библиотеки в его контексте.
Re[11]: проблема с pthread
От: VladimirV  
Дата: 23.09.03 13:43
Оценка:
Здравствуйте, naje, Вы писали:

А>>А что это что-то? у него наверное, есть pid и имя?


N>Мой процесс в топе вверху что-то делает хотя все потоки остоновлены.


А>>Может это lib'а доступа к БД запускает какой-нибудь свой thread?


N>Это libpq для PostreSql, раньше такого за ней не замечал.


Ну так подцепись к нему gdb и посмотри кто и чего делает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.