Membuat Thread di python


177

Saya memiliki skrip dan saya ingin satu fungsi berjalan pada saat yang sama.

Contoh kode yang telah saya lihat:

import threading

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

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

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

Saya mengalami masalah dalam menjalankan ini. Saya lebih suka menjalankan ini menggunakan fungsi berulir daripada kelas.

Ini skrip yang berfungsi:

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'

Jawaban:


323

Anda tidak perlu menggunakan subkelas Threaduntuk membuat karya ini - lihat contoh sederhana yang saya posting di bawah ini untuk melihat caranya:

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")

Di sini saya menunjukkan bagaimana menggunakan modul threading untuk membuat utas yang memanggil fungsi normal sebagai targetnya. Anda dapat melihat bagaimana saya bisa menyampaikan argumen apa pun yang saya perlukan untuk itu di konstruktor utas.


Saya sudah mencoba ini. Saya telah menambahkan skrip di atas. Bisakah Anda memberi tahu saya cara menjalankan fungsi kedua di samping yang pertama. Terima kasih
chrissygormley

6
@chrissygormley: gabung () blok sampai utas pertama selesai.
FogleBird

4
@chrissygormley: seperti yang disebutkan, gabung blok sampai utas yang Anda gabung selesai, jadi dalam kasus Anda, mulailah utas kedua dengan fungsi kedua Anda sebagai target untuk menjalankan dua fungsi secara berdampingan, lalu secara opsional bergabung dengan salah satu dari mereka jika Anda hanya ingin menunggu sampai selesai.
jkp

41
Saya terus membaca exitingsebagai exciting, yang saya pikir itu pula yang lebih tepat.
Chase Roberts

42

Ada beberapa masalah dengan kode Anda:

def MyThread ( threading.thread ):
  • Anda tidak dapat subkelas dengan suatu fungsi; hanya dengan kelas
  • Jika Anda akan menggunakan subclass yang Anda inginkan threading.Thread, bukan threading.thread

Jika Anda benar-benar ingin melakukan ini hanya dengan fungsi, Anda memiliki dua opsi:

Dengan threading:

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

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

Dengan utas:

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

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

Doc untuk thread.start_new_thread


2
Argumen kedua harus menjadi tuple untukthread.start_new_thread(function, args[, kwargs])
venkatvb

13

Saya mencoba menambahkan join lain (), dan sepertinya berhasil. Ini kode

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

Anda bisa menggunakan targetargumen di Threadkonstruktor untuk secara langsung meneruskan fungsi yang dipanggil alih-alih run.


2

Apakah Anda mengganti metode run ()? Jika Anda menimpanya __init__, apakah Anda memastikan untuk memanggil pangkalan threading.Thread.__init__()?

Setelah memulai kedua utas, apakah utas utama terus bekerja tanpa batas / blok / gabung pada utas anak sehingga eksekusi utas utama tidak berakhir sebelum utas anak menyelesaikan tugas mereka?

Dan akhirnya, apakah Anda mendapatkan pengecualian yang tidak ditangani?


Tidak ada pengecualian yang tidak ditangani dan utas utama harus dijalankan selama 30 menit. Saya tidak mengesampingkan __init__. Apakah perlu menjalankan ()? Terima kasih
chrissygormley

Saya baru menyadari bahwa teladan Anda adalah def MyThread ( threading.thread )... Saya berasumsi bahwa itu adalah definisi kelas. Jika Anda akan membuat subclass threading.thread dan menginisialisasi objek thread dengan target=Noneatau menghilangkan targetarg, maka diperlukan implementasi run (). Jika tidak, jika Anda hanya ingin menjalankan tugas sederhana di utas lain, lihat jawaban jkp.
Jeremy Brown

0

Python 3 memiliki fasilitas Peluncuran tugas paralel . Ini membuat pekerjaan kami lebih mudah.

Memiliki untuk penyatuan utas dan Proses penyatuan .

Berikut ini memberikan wawasan:

Contoh 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)))

Contoh lain

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()
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.