Tạo chủ đề trong python


177

Tôi có một kịch bản và tôi muốn một chức năng chạy cùng lúc với chức năng khác.

Mã ví dụ tôi đã xem:

import threading

def MyThread (threading.thread):
    # doing something........

def MyThread2 (threading.thread):
    # doing something........

MyThread().start()
MyThread2().start()

Tôi gặp khó khăn khi làm việc này. Tôi muốn có được điều này bằng cách sử dụng một hàm luồng hơn là một lớp.

Đây là kịch bản làm việc:

from threading import Thread

class myClass():

    def help(self):
        os.system('./ssh.py')

    def nope(self):
        a = [1,2,3,4,5,6,67,78]
        for i in a:
            print i
            sleep(1)


if __name__ == "__main__":
    Yep = myClass()
    thread = Thread(target = Yep.help)
    thread2 = Thread(target = Yep.nope)
    thread.start()
    thread2.start()
    thread.join()
    print 'Finished'

Câu trả lời:


323

Bạn không cần sử dụng một lớp con Threadđể thực hiện công việc này - hãy xem ví dụ đơn giản mà tôi đang đăng dưới đây để xem:

from threading import Thread
from time import sleep

def threaded_function(arg):
    for i in range(arg):
        print("running")
        sleep(1)


if __name__ == "__main__":
    thread = Thread(target = threaded_function, args = (10, ))
    thread.start()
    thread.join()
    print("thread finished...exiting")

Ở đây tôi chỉ ra cách sử dụng mô đun luồng để tạo một luồng gọi hàm bình thường làm mục tiêu của nó. Bạn có thể thấy làm thế nào tôi có thể chuyển bất kỳ đối số nào tôi cần cho nó trong hàm tạo của luồng.


Tôi đã thử điều này. Tôi đã thêm kịch bản lên trên. Bạn có thể cho tôi biết làm thế nào để chức năng thứ hai chạy cùng với chức năng thứ nhất. Cảm ơn
chrissygormley

6
@chrissygormley: các khối tham gia () cho đến khi chuỗi đầu tiên kết thúc.
FogleBird

4
@chrissygormley: như đã đề cập, tham gia các khối cho đến khi chuỗi bạn tham gia kết thúc, vì vậy, trong trường hợp của bạn, hãy bắt đầu một luồng thứ hai với chức năng thứ hai làm mục tiêu để chạy hai chức năng cạnh nhau, sau đó tùy ý nối một trong hai chức năng đó bạn chỉ muốn đợi cho đến khi chúng được thực hiện.
jkp

41
Tôi tiếp tục đọc exitingnhư exciting, mà tôi nghĩ rằng dù sao cũng phù hợp hơn.
Chase Roberts

42

Có một vài vấn đề với mã của bạn:

def MyThread ( threading.thread ):
  • Bạn không thể phân lớp với một hàm; chỉ với một lớp học
  • Nếu bạn định sử dụng một lớp con, bạn muốn phân luồng. Đọc, không phân luồng.thread

Nếu bạn thực sự muốn làm điều này chỉ với các chức năng, bạn có hai tùy chọn:

Với luồng:

import threading
def MyThread1():
    pass
def MyThread2():
    pass

t1 = threading.Thread(target=MyThread1, args=[])
t2 = threading.Thread(target=MyThread2, args=[])
t1.start()
t2.start()

Với chủ đề:

import thread
def MyThread1():
    pass
def MyThread2():
    pass

thread.start_new_thread(MyThread1, ())
thread.start_new_thread(MyThread2, ())

Tài liệu cho thread.start_new_thread


2
Đối số thứ hai phải là một tuple chothread.start_new_thread(function, args[, kwargs])
venkatvb

13

Tôi đã cố gắng thêm một tham gia () và có vẻ như đã hoạt động. Đây là mã

from threading import Thread
from time import sleep

def function01(arg,name):
    for i in range(arg):
        print(name,'i---->',i,'\n')
        print (name,"arg---->",arg,'\n')
        sleep(1)

def test01():
    thread1 = Thread(target = function01, args = (10,'thread1', ))
    thread1.start()
    thread2 = Thread(target = function01, args = (10,'thread2', ))
    thread2.start()
    thread1.join()
    thread2.join()
    print ("thread finished...exiting")

test01()

3

Bạn có thể sử dụng targetđối số trong hàm Threadtạo để truyền trực tiếp vào hàm được gọi thay vì run.


2

Bạn đã ghi đè phương thức run ()? Nếu bạn ghi đè __init__, bạn có chắc chắn gọi cho cơ sở threading.Thread.__init__()không?

Sau khi bắt đầu hai luồng, luồng chính có tiếp tục thực hiện công việc vô thời hạn / chặn / nối trên các luồng con để việc thực hiện luồng chính không kết thúc trước khi các luồng con hoàn thành nhiệm vụ của chúng không?

Và cuối cùng, bạn có nhận được bất kỳ ngoại lệ chưa được xử lý?


Không có ngoại lệ chưa được xử lý và luồng chính sẽ chạy trong 30 phút. Tôi đã không ghi đè __init__. Là run () cần thiết sau đó? Cảm ơn
chrissygormley

Tôi chỉ nhận ra rằng ví dụ của bạn là def MyThread ( threading.thread )... Tôi cho rằng đó là những định nghĩa lớp. Nếu bạn đang đi đến phân lớp luồng .thread và khởi tạo đối tượng luồng bằng target=Nonehoặc bỏ qua đối số target, thì cần phải thực hiện run (). Mặt khác, nếu bạn chỉ muốn chạy một tác vụ đơn giản trong một luồng khác, hãy xem câu trả lời của jkp.
Jeremy Brown

0

Python 3 có khả năng Khởi chạy các tác vụ song song . Điều này làm cho công việc của chúng tôi dễ dàng hơn.

Nó có để gộp nhómxử lý gộp .

Sau đây cung cấp một cái nhìn sâu sắc:

Ví dụ ThreadPoolExecutor

import concurrent.futures
import urllib.request

URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/',
        'http://some-made-up-domain.com/']

# Retrieve a single page and report the URL and contents
def load_url(url, timeout):
    with urllib.request.urlopen(url, timeout=timeout) as conn:
        return conn.read()

# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    # Start the load operations and mark each future with its URL
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        try:
            data = future.result()
        except Exception as exc:
            print('%r generated an exception: %s' % (url, exc))
        else:
            print('%r page is %d bytes' % (url, len(data)))

Một vi dụ khac

import concurrent.futures
import math

PRIMES = [
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419]

def is_prime(n):
    if n % 2 == 0:
        return False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return False
    return True

def main():
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))

if __name__ == '__main__':
    main()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.