![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
kulibinka |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 191 Регистрация: 20.11.2006 Репутация: 2 Всего: 4 |
Нужно сделать многопоточный закатчик картинок.
Разбирался с многопоточностью по этому коду http://effbot.org/librarybook/queue.htm. Немножко разобрался.
В файл 'images.txt' для теста положил следующие картинки Суть: скрипт получает файлик с урлами + сколько потоков одновременно запускать. Ну а после этого он начинает качать, но не все а только картинки. Эта моя версия качает успешно. Теперь вопрос: мне нужно чтобы он вел лог-файл. А вот как сделать так чтобы все потоки отдавали log_message в одно место я не знаю... В этом и вопрос - как при многопоточности сделать так, чтобы все потоки могли отсылать информацию в одно общее место? |
|||
|
||||
cherep |
|
||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 74 Регистрация: 11.1.2006 Где: Москва Репутация: 1 Всего: 4 |
Видимо нужно на время отсылки тредом информации залочить все остальные треды, поместив нужный тред в монитор (Хоара). Пока он в мониторе, может работать только он один, все остальные ждут. Таким образом можно предотвратить порчу разделяемого ресурса конкурирующими тредами. Для примера могу привести 2 кусочка кода. Сравните, как они работают.
Вывод:
Как видите, все "мешается" из-за того, что треды работают одновременно. Добавим кое-что:
Результат:
Как видите, мы окружили критический участок кода вызовами lock.acquire() и lock.release(). В данном случае lock и есть тем самым монитором (синхронизационным примитивом, если хотите ![]() |
||||||||
|
|||||||||
kulibinka |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 191 Регистрация: 20.11.2006 Репутация: 2 Всего: 4 |
Сделал как Вы посоветовали - заработало, спасибо
![]()
Вопрос в догонку - мне нужно запустить ф-ю сохранения лога только после того, как все потоки отработают. Как это делается - ввести переменную, в которой сохранять количество процессов, и перед сохранением циклить пока она не станет 0, или же есть какой-либо способ покрасивее? |
|||
|
||||
cherep |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 74 Регистрация: 11.1.2006 Где: Москва Репутация: 1 Всего: 4 |
Пожалуйста, я рад! На счет второго вопроса, думаю все что Вам нужно - это за-join-ить все запускаемые треды на главный тред (основной поток выполнения) Это хорошо написано в хэлпе. Теория тут такова: вы в треде A (в данном случае это основная программа) запускаете тред B: B.start() и сразу же делаете B.join() Таким образом тред A (основная программа) будет ожидать завершения треда B и лишь потом продолжит выполняться... На примере ранее приведенной программы
Вам нужно поставить сохранять лог на месте print 'All done!!!' ![]() |
||||
|
|||||
_Viper_ |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 87 Регистрация: 8.11.2006 Репутация: 10 Всего: 11 |
cherep, так как ты написал
Так же
|
||||||
|
|||||||
cherep |
|
||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 74 Регистрация: 11.1.2006 Где: Москва Репутация: 1 Всего: 4 |
Да, ты совершенно прав. Каждый вызов join просто-напросто будет блокировать работу цикла по запуску тредов до окончания последнего запущенного треда. Нужно делать так:
Насчет второго замечания, то тут ты не так понял. Суть в том, что весь участок будет выполнен как "единое целое". В данном случае да, потоки по большому счету будут выполняться последовательно. Нам важно было именно синхронизовать "всю записывающую" часть программы. Имеется ввиду, что там еще есть некоторая "полезная работа".
|
||||||||
|
|||||||||
_Viper_ |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 87 Регистрация: 8.11.2006 Репутация: 10 Всего: 11 |
||||
|
||||
cherep |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 74 Регистрация: 11.1.2006 Где: Москва Репутация: 1 Всего: 4 |
Это была имитация "протяженности" операции записи в лог ![]() |
||||
|
|||||
kulibinka |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 191 Регистрация: 20.11.2006 Репутация: 2 Всего: 4 |
Методом перебора пытался применить join к потокам если там еще и Queue прилеплено - все время вылазили ошибки.
А потом посмотрел http://docs.python.org/lib/QueueObjects.html и увидел что в питоне 2.5 можно делать банально queue.join(). Поставил 2.5, потестил - да, действительно можно и все работает ![]()
Спасибо всем за наводки. Но если кто подскажет как queue и join связать в 2.4 - буду немеряно благодарный ![]() |
|||
|
||||
_Viper_ |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 87 Регистрация: 8.11.2006 Репутация: 10 Всего: 11 |
|
|||
|
||||
kulibinka |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 191 Регистрация: 20.11.2006 Репутация: 2 Всего: 4 |
Ок.
Тогда другой вопрос - а что это моя программа ждет после того как все отработала? SAVED написала, все сделала (по результатам видно), и все равно продолжает что-то делать... |
|||
|
||||
cherep |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 74 Регистрация: 11.1.2006 Где: Москва Репутация: 1 Всего: 4 |
Самое простое и глупое решение - берешь файлик Queue.py из python25\Lib и ложишь в директории с исходником своей проги. Думаю, должно сработать. Идея, думаю, понятна - он будет импортироваться как в 24 так и в 25 -> все будет работать идентично. |
|||
|
||||
_Viper_ |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 87 Регистрация: 8.11.2006 Репутация: 10 Всего: 11 |
Такое бывает когда не все потоки закончили выполнение. Проверь нормально ли останавливаются твои потоки. |
|||
|
||||
kulibinka |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 191 Регистрация: 20.11.2006 Репутация: 2 Всего: 4 |
я так понимал что queue.join() для того и создано чтобы это проверять... Добавлено @ 20:07 проверил - запустил все в один поток оно все сделало, отчиталось, но все продолжает чего-то ждать... |
|||
|
||||
cherep |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 74 Регистрация: 11.1.2006 Где: Москва Репутация: 1 Всего: 4 |
Попробуй глянуть чему равно
Попробуй в самом конце
PS. А вообще совет. Попробуй добиться того же эфекта (описанный баг) на более простом случае (те же потоки, но без закачки картинок). Если будет также - пости сюда, нам будет легче тебе помочь. Это сообщение отредактировал(а) cherep - 12.12.2006, 21:21 |
||||
|
|||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Python: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |