По теме: ну почему у тебя всё не как у людей? :( Через prctl это делается, тем или иным способ тащи его в питон. В общем, тебе нужен ctypes если не хочешь плодить зависимости. Но я бы взял готовый модуль — не надо на каждый чих изобретать велосипеды, это моя привилегия :)
Я про prctl в этой теме первый раз услышал, я ж не программист.
По сабжу - нахрена мне prctl или ctypes, если я могу просто сформировать временный файл с нужным именем и его запустить? Это будет ровно на одну строчку кода больше, я все равно для этого процесса код на лету формирую...
Лор такой лор, даже вы с tailgunner-ом уже не те... ;-)
Это будет ровно на одну строчку кода больше, я все равно для этого процесса код на лету формирую...
Смотря как ты этот код генерируешь. Технически это валидное решение, но как оно выглядит на фоне другого кода — хз, ты же нам ничего не показываешь.
В общем случае, я бы не хотел чтобы процессы переименовывали через временные исполняемые файлы. И точно не люблю когда имя процесса меняют до неузнаваемости так что приходится юзать pstree чтобы понять что к чему (и то после double fork всё превращается в тыкву). Лучше добавляй суфикс со статусом как это делают белые люди (cast tailgunner?). Например, как в nginx:
--# ps ax| grep nginx
2747 ? Ss 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
12183 ? S 2:22 nginx: worker process
12188 ? S 2:09 nginx: worker process
Ну и есть одна болезнь — боязнь зависимостей. Я тоже этим болею, но не до такой степени. В общем, главное вовремя останавливать свой завод по производству велосипедов.
Мне показалочь что я в исходном посте вполне достаточно рассказал;-)
У меня есть база для результатов работы чиcлодробилок, база тупо на файлах - каждый расчет сливает данные в свою директорию, в директории есть файлик который в формате pickle хранит параметры и состояние расчета.
Скрипт о котором идет речь следит за работой запустившего его приложения, и при необходимости (если приложение упало/было убито киллом и не смогло обновить свой статус) отмечает в файле с параметрами что оно таки померло, иначе потом при построении выборки проблемы начинаются.
Раньше запускал отдельный скрипт (уже готовый), но тут понял что незачем (его устанавливать надо же куда то + непонятно по ps что он контролирует). Сейчас делаю так
if Calc._statechecker:
import inspect
f = open('/tmp/racs-schk-%i'%os.getpid(), 'w')
print>>f, '''#!/usr/bin/python -S
# -*- coding: utf-8 -*-
import os, sys, cPickle, time, socket
d2s = lambda t: time.strftime('%Y.%%m.%d-%X', time.localtime(t))
'''
print>>f, inspect.getsource(get_login)
print>>f, inspect.getsource(mk_daemon)
print>>f, inspect.getsource(set_output)
print>>f, '''mk_daemon(); set_output()
while 1 :
if '%i' in os.listdir('/proc/'): time.sleep(10)
else:
R = cPickle.load(open(%r+'.RACS'))
if R['statelist'][-1][0]=='started':
R['statelist'].append(('killed', get_login(), socket.gethostname(), d2s(time.time()), 'racs-statechecker'))
cPickle.dump(R, open(%r+'.RACS', 'w'))
break
'''%(os.getpid(), self.path, self.path)
f.close(); os.chmod(f.name, 0700); os.system(f.name); os.remove(f.name)
ну было бы как то
f = popen('python -S', 'w')
print>>f, '''# -*- coding: utf-8 -*-
import os, sys, cPickle, time, socket
...
f.close(); # и как то меняем имя процесса
Кстати раз пошла такая пьянка, еще нубский вопрос от не-программиста;-)
У меня есть очередь заданий (тяжелых, невзаимодействующих), которую я хочу обработать на одном хосте в несколько потоков. Очередью рулит мастер-процесс. Если в одном потоке все понятно, мастер в цикле берет очередное задание из очереди, форкается, и дальше родитель ждет завершения потомка а потомок собственно идет дальше и выполняет задание (считает), и так пока не закончатся задания. Долго объяснять почему, это в данном случае оптимальная архитектура.
Как это сделать в несколько потоков (что бы у меня одновременно обрабобатывалось несколько заданий)? Зарядить несколько обычных тредов с функцией обработки очереди? Там же GIL и вот это вот все, и вообще я не очень соображу как треды с форком будут жить...
Кодинг-стайл, error handling, модуль logging? Не, не слышал.
В общем, мои самые худшие опасения подтвердились. Как указал i-rinat, тебе нужен os.waitpid. Помимо этого, для питона есть хорошие готовые либы для параллельных вычислений которые берут большинство проблем на себя. Что-то вроде mpi4py.
Можешь смело выбросить весь код и переписать с нуля использованием нормальных библиотек. В данном случае я абсолютно уверен что написание своих костылей чрезвычайно вредит коду.
Ещё смело исходи из того что на любое событие в системе можно сделать асинхронный обработчик, достаточно только погуглить. Т.е., для наблюдения за файлами, сокетами, процессами этц не нужны никакие треды, нужно использоваться всякие select/poll/whatever и вообще asyncio.
Далее, не понятно почему нужно что-то подчищать в данных упавшего приложения. Обычно просто делают флаг dirty для того чтобы понимать консистенты ли данные или нет (https://en.wikipedia.org/wiki/Dirty_bit).
Наконец, я подозреваю что у тебя перепаковываются pickle-файлы os.system(f.name)на каждый чих что не есть тру.
os.system
Тебе нужен subprocess. os.spawnvp в примере i-rinat просто для демонстрации, в реальности subprocess удобнее (особенно если это третий питон).
Ну блин... я с телефона щас пишу, неудобно катать простыни... Я в ахуе. Вы с tailgunner одни из самых вменяемых людей на лоре, но если вы пишете такое - я понимаю почему на моей полянке от настоящих программистов нет как правило вообще никакого толку...:-(
Нет мне НЕ нужен mpi4py. И я не хочу говорить о Господе нашем, и о Иегове. Ребят, Вы когда ТЗ читаете так же отвечаете?!
— Мне нужно помыть руки с помощью Lego Mindstorm.
— Э-э... Возьми мыло, сунь руки под струю воды...
— Нет, мне НЕ нужно мыло. И вода не нужна. И я не хочу говорить о Господе нашем, и о Иегове. Ребят, Вы когда ТЗ читаете так же отвечаете?!
У меня русским языком написано, что мастер-процесс должен использовать форк. И причем тут spawn или subprocess, mpi4py и т.д.?
Насчет «просто форкнуться» - у меня есть 10000 заданий, но одновременно может выполняться скажем не более четырех. Вариант разбить очередь на 4 куска по 2500 и обрабатывать их независимо не проходит, задания могут иметь разное время выполнения, заранее неизвестно какое.
AIv★★★★★ ()автор топика
Последнее исправление: AIv
(всего
исправлений: 1)
import os, sys, time, random
queue = range(20)
pids = []
for q in queue:
while len(pids)==4:
time.sleep(1)
pids = filter(lambda p: os.waitpid(p, os.WNOHANG)[0]==0, pids)
print pids
pid = os.fork()
if not pid: break
pids.append(pid)
else:
# непонятно почему тут не работает os.wait()?
while pids:
time.sleep(1)
pids = filter(lambda p: os.waitpid(p, os.WNOHANG)[0]==0, pids)
print 'end', pids
print 'finished'; sys.exit()
# это типо выполнение задания
random.seed(os.getpid())
t = 5+random.uniform(-2,2)
print os.getpid(), q, 'start', t
time.sleep(t)
print os.getpid(), q, 'OK'
только мне концовка не нравится (блок else) - как то горомоздко, а обычный os.wait() не помогает почему то.
Имхо, нельзя два раза вызывать waitpid (и аналогичные функции) на один и тот же pid (ибо это одноразовый clean-up action). Опять-таки, зачем ты делаешь поллинг в цикле если waitpid может сам ждать наступление нужного события (хинт — убери sleep и os.WNOHANG)?
Ну а так всё страшненько. Есть же multiprocessing, есть другие готовые средства... Я надеюсь что ты рано или поздно поймёшь что так писать код нельзя. Я бы взялся отрефакторить этот кусок но, боюсь, тебя это не убедит, ведь «и так работает, зато зависимостей нету».
от настоящих программистов нет как правило вообще никакого толку
Тебя обманули, я неплохо вытягиваю проекты типа того что ты здесь показываешь :). Приходится ругаться с программистами, переделывать за них, но рано или поздно они признают ошибку. Правда, не всегда, спорить с «а моим способом оно тоже работало» и «это редкая ошибка, отлавливать не обязательно» очень сложно.
Если ни один порожденный процесс не завершился, вернуться немедленно. Таким способом можно периодически проверять, не закончился ли какой- нибудь порожденный процесс. (Такая периодическая проверка известна как опрашивание события.)"
«Для того, чтобы процесс не оставлял зомби, можно вызывать функцию waitpid() периодически (с флагом NOHANG, чтобы она не блокировала вызвавший процесс если в системе нет зомби).»
Что полностью отвечает здравому смыслу (иначе напуркуа такую опцию вообще вводить)?
Опять-таки, зачем ты делаешь поллинг в цикле если waitpid может сам ждать наступление нужного события (хинт — убери sleep и os.WNOHANG)?
Подумай? Вот у меня форкнуто четрые процесса, три быстро завершились а один затупил, и я вишу на его waitpid-е. Клево? Это называется «разбалансировка загрузки». Вот в ветке else так можно сделать, да
else:
for p in pids: os.waitpid(p, 0)
print 'finished'; sys.exit()
это я потом, спросонья уже допер;-)
Есть же multiprocessing, есть другие готовые средства...
Я начинаю за тебя волноваться. Сколько раз мне нужно повторить, что жестким и необходимым требованием в данном случае является прямой вызов форка? Кроме того, я не очень понимаю нафига мне монстр-multipricessing, если задачи НЕ взаимодействуют. Ну кроме того, что мастер поглядывает кто досчитался и запускает следующего - как то на полноценное взаимодействие это ИМНО не тянет...
Тебя обманули, я неплохо вытягиваю проекты типа того что ты здесь показываешь :)
Пока я этого не заметил, извини. Кроме того, я тут не говорю о ПРОЕКТЕ целиком - я говорю о мааааленьком фрагменте большой задачи. И твоя реакция - реакция настоящего программиста «у вас тут усе ужастно и страшно, так делать совсем нельзя, давайте все перепишем стандартными средствами (и еще прикрутим шлюх, блэкджек и SQL/dbus/веб сервис)». То, что при этом задача потеряет смысл из виду упускается. Именно поэтому на моей полянке от настоящих программистов толку мало - вы гораздо лучше знаете как правильно писать программы, но вам довольно сложно объяснить что именно нужно написать, крайне сложно объяснить зачем это нужно написать, и совершенно невозможно объяснить почему нужно написать именно это, а не что то иное.
AIv★★★★★ ()автор топика
Последнее исправление: AIv
(всего
исправлений: 2)
На изначальный вопрос тебе ответили первым же сообщением. На него ты ругнулся, но когда тебе написали то же ещё раз, заявил, что это норм. Так что тут твои вопли не оправданы.
Потом речь зашла об общих механизмах обработки. Тут ты начал как обычно кичиться. Даже сейчас, с этим примером с набегающей волной ты никак не можешь понять, что мытьё рук решает задачу очистки рук, а сборка набегающей волны не решает ничего. Это просто какой-то фрагмент решения. И далеко не факт, что путь был выбран верно.
Тебя всеми способами пытаются спросить, а тот ли ты путь выбрал? Может статься, ты карабкаешься на крутую гору вместо того, чтобы сесть на поезд, который тебя довезёт на другую сторону. Альпинистов ещё можно понять, они от этого кайф ловят. А ты просто страдаешь. И ещё причитаешь, мол, какой плохой ЛОР, не понимает, как на гору карабкаться, один я такой умный, а все дураки. Ай-ай-ай, ЛОР такой ЛОР.
реакция настоящего программиста «у вас тут усе ужастно и страшно, так делать совсем нельзя, давайте все перепишем стандартными средствами
Ты самую суть схватил. Только вот то, что ты осуждаешь, на самом деле хорошо. Суть использования стандартных средств — в снижении сложности, а ты её увеличиваешь.
На изначальный вопрос тебе ответили первым же сообщением.
Формально ответили, по сути этот ответ (кроме моего образования) был совершенно бесполезен. Что бы понять, что этот ответ бесполезен, достаточно было внимательно прочитать вопрос. Или ты всерьез считаешь что танцы с prctl и ctypes проще/лучше чем запуск налету сформированного файла с нужным именем, при том что запускаемый код в любом случае формируется налету?
Тут ты начал как обычно кичиться.
Я не кичусь ни разу - я фигею с людей, которым лень прочитать внимательно вопрос и подумать (и помолчать если нечего сказать по теме), но не лень писать простыни текста не по делу. КТо из нас кичится то? Я то не утверждаю что ты все делаешь не так;-)
Даже сейчас, с этим примером с набегающей волной ты никак не можешь понять, что мытьё рук решает задачу очистки рук, а сборка набегающей волны не решает ничего.
Сборка набегающей волны решает задачу сборки набегающей волны. Я конечно могу начать рассказыват все от печки, но:
1) это займет ооочень много времени, которого нету ни у меня, ни у слушателей, да и большинству это будет не очень интересно.
2) мне придется объяснять аудитории некоторые вещи лежащие за рамками программирования, которые для аудитории будут не вполне понятны/интересны в силу специфики предметной области.
3) все это придется делать под выкрики неадекватов типа postman_
4) в итоге выяснится что выбранный путь достаточно оптимален, потому что я этим занимаюсь уже 15 лет, и все коллеги делающие похожие вещи насколько я знаю делают их примерно так же (с поправкой на специфику их задач).
Но твоя реакция тоже вполне ожидаемая реакция «настоящего программиста»(ТМ).
Тебя всеми способами пытаются спросить, а тот ли ты путь выбрал?
Если мне захочется обсудить выбранный путь в этой аудитории - я спрошу, спасибо за участие. Лор такой лор...
Альпинистов ещё можно понять, они от этого кайф ловят.
Ты хочешь поговрить со мной за альпинизм? Давай;-)
ЛОЛ... ну давай, приведи решение для исходной темы через prctl/ctypes и потом мы попытаемся его запустить на произвольном кластере... а потом когда доведем до ума, сравним по сложности с моим.
Или попытайтся привести решение задачи с очередью через multiprocessing/spawn, и я объясню тебе почему это не будет работать. Ты начнешь кричать «этого не было в условии!» на что я тебе резонно отвечу «в условии было оговорено использование форка». И после того, как ты доведешь свое решение до приемлемого уровня, мы сравним его сложность с решением через форк.
С чего ты взял что fork/waitpid нестандартны я кстати ума не приложу... у меня коллеги свой MPI на питоне забацали (со всякими дополнительными плюшками), вот это было нестандартно, да.
Если мне захочется обсудить выбранный путь в этой аудитории - я спрошу, спасибо за участие. Лор такой лор...
КТо из нас кичится то?
Ты. Тебе самому это, наверное, не так заметно.
конечно могу начать рассказыват все от печки, но
Если в твоей аналогии так много «но», значит она плохая. Обрати внимание, что ни Лего, ни мытьё рук мне тебе не понадобилось описывать. А ты в ответ бросаешь специфику, которую заведомо не все участники знают. Ты так самоутверждаешься?
Если ты хочешь общаться со знаниями, попробуй общаться с Большой Советской Энциклопедией. Она битком набита знаниями.
в итоге выяснится что выбранный путь достаточно оптимален
Во-первых, ты мог бы это просто описать парой предложений, вместо того, чтобы по нескольку раз писать в стиле: «Нет! Нет! Как ты не понимаешь?!» А во-вторых, оптимальность твоего кода под вопросом. Те куски, которые ты приводил, страшные. По его виду не понятно, что это вылизанное решение, выглядит как нагромождение хаков. Собственно, тебе про это и писали. Кто-то вежливо, кто-то нет.
Меня кастанули в тред, и я удивился тому, что почтенные господа до сих пор распинаются перед ученым-моченым. Оставьте человека в покое, пусть дальше лепит свои портянки, а еще лучше — посоветуйте лисп. Видно же, что его не интересует поддерживаемость, а волнуют только ТАК ВСЕ В МОЕМ НИИ ДЕЛОЮТ и ПАД МАЮ ЗАДАЧУ ПАДХОДИТ.
У меня для тебя плохие новости - твое решение не подходит. Мне нужно решение, которое прдключается в пользовательский код одной строчкой
import X
где X - имя обсуждаемого модуля. А твое решение требует серьезной модификации пользовательского кода, выделение задачи в отдельную функцию для запуска и т.д. Ты конечно можешь заюзать inspect, заняться анализом стека и т.д. - но только не говори мне потом о снижении сложности.
Т.е. я говорю тебе что ты все делаешь не так? Где?
А ты в ответ бросаешь специфику, которую заведомо не все участники знают. Ты так самоутверждаешься?
Интересные у тебя реакции... я просто пытаюсь услышать ответ на интересующий меня вопрос, а ты тут психоанализ уже привлек. Ты уверен что это не твои проекции? Хочешь поговорить об этом? Нет, для самоутверждения я давно использую не ЛОР а другие способы.
Если ты хочешь общаться со знаниями, попробуй общаться с Большой Советской Энциклопедией. Она битком набита знаниями.
Не говори мне с кем общаться а с кем нет. Можешь просто добавить меня в блэклист.
Во-первых, ты мог бы это просто описать парой предложений,
пары бы не хватило.
вместо того, чтобы по нескольку раз писать в стиле: «Нет! Нет! Как ты не понимаешь?!»
Ну что же делать, если ты не понимаешь...
А во-вторых, оптимальность твоего кода под вопросом.
Я не говрю про оптимальность кода - я говорю про оптимальность подхода. И я не думаю, что бы ты был достаточно компетентен что бы делать выводы об оптимальности подхода - знание специфики и вот то вот все... ;-)
Это, батенька, опыт :). Если серьёзно то прочитай про зомби-процессы и SIGCHILD.
и я вишу на его waitpid-е
waitpid может мониторить все дочерние процессы сразу: «If pid is -1, the request pertains to any child of the current process». Доки не читаем? :)
я говорю о мааааленьком фрагменте большой задачи
Это-то и пугает :). Понимаешь, вот тут простой фрагмент, а уже столько проблем вылезло. Я уверен что твой код никто кроме тебя понять не сможет. Потому что так никто не пишет и на то есть причины. Ты сейчас борешься с ветряными мельницами — тратишь второй день своей жизни на задачи которые давно уже решены и решены гораздо лучше чем ты можешь сделать. Серьёзно, ты не знаешь как работают процессы в линуксе и пишешь свой велосипед? No way.
сложно объяснить что именно нужно написать
Уж менеджер процессов-то написать сможем, не сомневайся :). Сбор требований и постановка задачи очень сложные вещи. Естестно что твои студенты которые «в теме» смогут быстрее приступить к быдлокодингу чем нормальный адекватный программист которому сначала нужно объяснить что делать. Причём, я вижу, ты очень любишь людей сбивать с толку диктуя свои «решения», вместо того чтобы послушать как это надо делать на самом деле. Не, так это не работает.
А waitpid (-1) зацепит потомков дочерних процессов (если кто то из них отвалится)? Или потомков дочерних процессов должны слушать сами дочерние процессы?
ЗЫ вот веб браузер для андроида из которого я сейчас отвечаю тоже писал настоящий программист же... небось стандартными средствами и код хороший. Но такое кривое уе-ще вышло...:-(
А waitpid (-1) зацепит потомков дочерних процессов (если кто то из них отвалится)?
Вот так не помню, скорее всего нет (гугли waitpid grandchildren). Но в данном случае это неважно, у тебя же есть список всех pid-ов. Если что лишнее прилетело то тупо игнорируешь.
настоящий программист
Надоела эта истерика что вокруг все дураки, а вот ты единственный кто знает как надо писать программы. Извини, у меня никакого желания помогать, больше не кастуй меня.
А мне то как надоело слушать вместо ответа на впрлне конкретно поставленный вопрос какой я (все ученые) дурак/дураки!
То, что критерии качества кода могут быть разные - это непонятно? То, что критерии продакшена не являются актуальными в других областях - это непонятно? Показать тебе код одной совершенно уникальной, офигительной числодробилки, благодаря котороый было открыто несколько крупных месторождений нефти и газа в РФ в последние 10 лет? основная часть написана в одно лицо (не мной - совершенно гениальный дядька из нашего института), код совершенно жуткий по вашим критериям (и поддежка почти невозможна, факт).
Не было такого в треде. Если что, я некоторое отношение к науке имею. Но я вот вижу обратное обобщение — какие программисты дураки. А на самом деле обобщать нельзя, средняя температура по больнице абсолютно бесполезна для описания распределения популяции. Если учил статистику то поймёшь о чём я.
критерии качества кода могут быть разные
Ты путаешь качество кода с качеством решения задачи. Никто не говорит что ты не можешь уехать на том что есть, ты просто далеко не уедешь. Возможно, вам это и не нужно. Просто не надо питать иллюзий по поводу качества того что вы пишите.
Потом, ты должен хотеть писать хороший код в первую очередь для себя. Это прямой путь к повышению продуктивности. Кривые глючные скрипты это зло. Но, опять-таки, у вас своя специфика. Но всё же тут раздел для программистов и стрельба по ногам не поощряется, даже если ты этого сильно просишь и категорически отвергаешь другие пути.
да ну? Видать я такой мнительный, не первый тред это наблюдаю? Почитай что ли комменты постмана например...
Но я вот вижу обратное обобщение
Виноват, делюсь скромным личным опытом. И кстати я не называл никого дураком, если уж на то пошло;-) Напротив, я признаю что программисты умеют писать хороший код куда лучше чем я. Когда я это понял, я перестал считать себя программистом - слишком мало в этой области знаю, недостоин.... я серьезно.
Общение с вашим братом чем то похоже на общение с математиками;-)
Ты путаешь качество кода с качеством решения задачи.
Нет, я не путаю. Печальный факт - код абсолютного большинства числодробилок (а я их повидал от разных аффторов из разных стран) совершенно ужастен по критериям не только продакшена, но и вообще на любой сторонний взгляд. Я не к тому что это хорошо, это плохо - но это факт. Тем не менее они работают, работают хорошо (в смысле выполняют свои функции), и в них заложены очень интересные алгоритмы и всех все устраивает (пока не доходит до поддержки/рефакторинга со стороны, но это бывает крайне редко).
Потом, ты должен хотеть писать хороший код в первую очередь для себя. Это прямой путь к повышению продуктивности.
Совершенно не спорю, я к этому стремлюсь в силу своих скромных возможностей. Но гораздо больше я стремлюсь получать результаты.
У нас как правило код не является результатом, результатом является продукты его работы - фалйлы с чиселками и картинки. Если (иногда) результатом является код - то его оценивают по функциональности (производительности, набору моделируемых явлений и пр), а не по красоте дизайна, правильности программистких решений и пр. Такие дела.
категорически отвергаешь другие пути.
Понимаешь, я хотя и не считаю себя программистом, но набор возможный путей как правило представляю... И чего скажем вы с Ринатом взъелись на прямой вызов форка мне непонятно, обычный системный вызов... это с каких пор стало «стрельбой по ногам» O_O?
Под винду не переноcим? Так и хрен бы с ним, это я переносить не собирался.
Я пробовал устраивать мосговой штурм с каким нить проф.программистом - когда все разжуешь и объяснишь, в итоге оказывается что выбранный изначально путь близок к оптимальному. «Личный опыт» как ты сам говорил;-)