Как "сгенерировать" несколько клиентов TCP с помощью потоков, вместо того чтобы открывать несколько экземпляров терминала и запускать script несколько раз?
Я написал код для простого клиента TCP:
from socket import *
# Configurações de conexão do servidor
# O nome do servidor pode ser o endereço de
# IP ou o domínio (ola.python.net)
serverHost = 'localhost'#ip do servidor
serverPort = 50008
# Mensagem a ser mandada codificada em bytes
menssagem = [b'Ola mundo da internet!']
# Criamos o socket e o conectamos ao servidor
sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.connect((serverHost, serverPort))
# Mandamos a menssagem linha por linha
for linha in menssagem:
sockobj.send(linha)
# Depois de mandar uma linha esperamos uma resposta
# do servidor
data = sockobj.recv(1024)
print('Cliente recebeu:', data)
# Fechamos a conexão
sockobj.close()
Я хотел бы знать, как "сгенерировать" несколько клиентов TCP с помощью потоков, вместо того, чтобы открывать несколько экземпляров терминала и несколько раз запускать script.
Ответы
Ответ 1
Попробуйте следующее:
Рабочий метод будет установлен в качестве цели для потока.
Поэтому каждый поток будет использовать код метода.
После запуска всего потока цикл for в нижней части будет ждать завершения всех потоков.
В рабочем методе вы можете использовать массивы или списки данных вне метода. Таким образом, вы можете итерировать, например, по списку Urls или добавить полученные данные в новый выходной массив.
import threading
threads = []
maxNrOfThreads = 5
def worker():
do_stuff()
for _ in range(maxNrOfThreads):
thr = threading.Thread(target=worker)
threads.append(thr)
thr.setDaemon(True)
thr.start()
for thread in threads:
thread.join()
Ответ 2
Я только что завернул ваш код/то, что вы хотите сделать, в функцию i.e. worker()
. Затем я добавил дополнительный код для thread
spawning и установил worker()
как функцию target
(будет выполняться функция/работа/код каждого порожденного потока - вот почему это соглашение, чтобы назвать его worker
).
th = threading.Thread(target=worker)
Многопоточная версия, приведенная выше, может быть следующей:
import threading
from socket import *
serverHost = 'localhost'#ip do servidor
serverPort = 50008
threads = []
input = input("Enter the number of threads:")
num_of_threads = int(input)
def worker():
# Criamos o socket e o conectamos ao servidor
sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.connect((serverHost, serverPort))
# Mandamos a menssagem linha por linha
for linha in menssagem:
sockobj.send(linha)
# Depois de mandar uma linha esperamos uma resposta
# do servidor
data = sockobj.recv(1024)
print('Cliente recebeu:', data)
sockobj.close()
# thread generation block
for t in range(num_of_threads):
th = threading.Thread(target=worker)
threads.append(th)
th.setDaemon(True)
th.start()
for thread in threads:
thread.join()
Ответ 3
Вот одно решение с очередями отправки отдельных сообщений.
#!/usr/bin/python
import Queue
import threading
import time
from socket import *
DEF_HOST = 'localhost'
DEF_PORT = 50008
queueLock = threading.Lock()
class myThreadTCP (threading.Thread):
def __init__(self, host=DEF_HOST, port=DEF_PORT, q=None):
threading.Thread.__init__(self)
self.host = host
self.port = port
self.q = q
def run(self):
global queueLock
print("Starting Thread")
# Criamos o socket e o conectamos ao servidor
sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.connect((self.host, self.port))
while not workQueue.empty():
with queueLock:
data = q.get()
if data:
print("sending %s" % data)
sockobj.send(data)
# Depois de mandar uma linha esperamos uma resposta
# do servidor
data = sockobj.recv(1024)
print('Cliente recebeu:', data)
# Fechamos a conexão
sockobj.close()
print("Exiting Thread")
workQueue = Queue.Queue()
# Mensagem a ser mandada codificada em bytes
menssagem = [b'Ola mundo da internet!', b'Ola mundo da internet #2!']
for msg in menssagem:
workQueue.put(msg)
threads = []
# Create 10 new threads
for i in range(0, 10):
thread = myThreadTCP(host=DEF_HOST, port=DEF_PORT, q=workQueue)
thread.daemon = True
thread.start()
threads.append(thread)
# Wait for all threads to complete
for t in threads:
t.join()
print("Exiting Main Thread")
Ответ 4
Простейший и самый pythonic способ использовать многопроцессорную реализацию пула потоков, а затем вызывать pool.map
. Первый позволит вам без проблем переходить от потоков к процессам, когда это необходимо. Последний предоставит вам чистый интерфейс, скрывающий операции синхронизации за кулисами.
#!/usr/bin/env python3
import socket
from pprint import pprint
from contextlib import closing
from multiprocessing.dummy import Pool as ThreadPool
serverHost = 'localhost'
serverPort = 80
messageGroups = [
[b'GET / HTTP/1.0\n\n'],
[b'GET /some-path HTTP/1.0\n\n'],
]
def send(messages):
result = []
options = socket.AF_INET, socket.SOCK_STREAM
with closing(socket.socket(*options)) as sockobj:
sockobj.connect((serverHost, serverPort))
for message in messages:
sockobj.send(message)
response = sockobj.recv(1014)
result.append((message, response))
return result
if __name__ == '__main__':
size = 10
pool = ThreadPool(size)
result = pool.map(send, messageGroups)
pool.close()
pool.join()
pprint(result)