Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 12, 2013 19:43:28

kloma
Зарегистрирован: 2013-09-12
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Мультипроцессинг

Здравствуйте, нужна помощь с мультипроцессингом.
Изначальный скрипт:

import socket
import time
start = time.clock()
with open('test.txt') as f:
    l = f.read().splitlines()
f.close()
for x in l:
    try:
       print (socket.gethostbyname(x))
        
    except socket.gaierror:
        print('error',end=' ')
        print (x)
        pass
end = time.clock()
print ('Time: %s' % (end - start))

Скрипт берет из файла домены и получает ip. Сперва попробовал ускорить потоками, но ничего хорошего из этого не вышло – время выполнения такое же как и без потоков.

Скрипт с потоками:
#!/usr/bin/env python
from threading import Thread
import subprocess
from queue import Queue
import socket
import time
start = time.clock()
with open('test.txt') as f:
    l = f.read().splitlines()
f.close()
num_threads = 3
queue = Queue()
def getip(i, q):
    while True:
        
        ip = q.get()
        try:
            print(socket.gethostbyname(ip))
        except socket.gaierror:
            print('error',end=' ')
            print (ip)
            pass
        q.task_done()
for i in range(num_threads):
    worker = Thread(target=getip, args=(i, queue))
    worker.setDaemon(True)
    worker.start()
for ip in l:
    queue.put(ip)
print ("Main Thread Waiting")
queue.join()
print ("Done")
end = time.clock()
print ('Time: %s' % (end - start))

Попробовал сделать мультипроцессинг:
#!/usr/bin/env python
from queue import Queue
import socket
import time
from multiprocessing import Process
start = time.clock()
with open('test.txt') as f:
    l = f.read().splitlines()
f.close()
num_threads = 3
queue = Queue()
def getip(i, q):
    
    while True:
        
        ip = q.get()
        try:
            print(socket.gethostbyname(ip))
        except socket.gaierror:
            print('error',end=' ')
            print (ip)
            pass
        q.task_done()
if __name__ == '__main__':
    for i in range(num_threads):
        worker = Process(target=getip, args=(i, queue))
        worker.start()
for ip in l:
    queue.put(ip)
print ("Main Thread Waiting")
queue.join()
print ("Done")
end = time.clock()
print ('Time: %s' % (end - start))

Скрипт выдает
_pickle.PicklingError: Can't pickle <built-in method release of _thread.lock obj
ect at 0x0000000028C10B00>: it's not found as __main__.release

Подскажите как исправить



Отредактировано kloma (Сен. 12, 2013 19:44:21)

Офлайн

#2 Сен. 12, 2013 20:50:49

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Мультипроцессинг

Наверное, потому что вы пихаете instance обычной Queue, которая не знает ничего про multiprocessing.
Попробуйте from multiprocessing import Queue

Офлайн

#3 Сен. 12, 2013 21:47:18

kloma
Зарегистрирован: 2013-09-12
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Мультипроцессинг

Теперь скрипт работает но не завершается т.к пришлось убрать q.task_done() и queue.join()
Чем заменить для multiprocessing ?

Офлайн

#4 Сен. 13, 2013 00:05:19

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Мультипроцессинг

Офлайн

#5 Сен. 13, 2013 00:31:34

kloma
Зарегистрирован: 2013-09-12
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Мультипроцессинг

если добавляю q.task_done() получаю ошибку:
AttributeError: ‘Queue’ object has no attribute ‘task_done’
________
Так же пробовал так:

if q.get() == 'None':
            break

не сработало

Отредактировано kloma (Сен. 13, 2013 00:36:46)

Офлайн

#6 Сен. 13, 2013 07:41:29

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Мультипроцессинг

kloma
возьмите лучше отдельный модуль Queue, вот тут написано по русски с примерами, без проблем все сделаете.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#7 Сен. 13, 2013 07:44:31

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Мультипроцессинг

если добавляю q.task_done() получаю ошибку:
AttributeError: ‘Queue’ object has no attribute ‘task_done’
Я вам уже даже прямую ссылку на документацию, вы читать умеете?

Офлайн

#8 Сен. 13, 2013 07:46:16

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Мультипроцессинг

возьмите лучше отдельный модуль Queue, вот тут написано по русски с примерами, без проблем все сделаете.
“Отдельный” т.е. стандартный Queue не подойдёт, он использует multiprocesssing. К вам такой же вопрос, вы читать умеете, читали, о чём топик?

Офлайн

#9 Сен. 13, 2013 10:30:24

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Мультипроцессинг

lorien
да, умею. Оцениваю задачу из первого поста, а конкретно из изначального скрипта. Задачу можно решить по разному, и ее можно решить за счет потоков (что автор и пытался сделать, но по неведомой причине у него не получилось, что мне кажется просто недочетом)



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#10 Сен. 15, 2013 15:54:34

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Мультипроцессинг

У меня мало опыта работы с socket/threading, не помню есть ли там проблема, что если один сокет подвисает, то подвисают все или это только с urllib/threading связано.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version