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'
chrissygormley
sumber

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.

jkp
sumber
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

Jorenko
sumber
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()
GGG
sumber
3

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

unholysampler
sumber
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?

Jeremy Brown
sumber
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()
Jeril
sumber