在python中创建线程


186

我有一个脚本,我希望一个函数与另一个函数同时运行。

我看过的示例代码:

import threading

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

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

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

我在进行这项工作时遇到了麻烦。我更愿意使用线程函数而不是类来实现这一点。

这是工作脚本:

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'

Answers:


337

您无需使用的子类Thread即可完成这项工作-请看一下我在下面发布的简单示例,了解如何:

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

在这里,我展示了如何使用线程模块创建一个线程,该线程调用普通函数作为其目标。您可以看到如何在线程构造函数中将所需的任何参数传递给它。


我已经试过了。我在上面添加了脚本。您能告诉我如何让第二个功能与第一个功能一起运行吗?谢谢
chrisg 2010年

6
@chrissygormley:join()会阻塞,直到第一个线程完成。
FogleBird

4
@chrissygormley:如前所述,连接块直到您要连接的线程完成为止,因此,在您的情况下,以第二个函数为目标启动第二个线程并排运行两个函数,然后在可能的情况下加入其中一个您只想等待,直到完成。
jkp 2010年

46
我一直读exitingexciting,我认为还是更合适。
Chase Roberts

43

您的代码存在一些问题:

def MyThread ( threading.thread ):
  • 您不能使用函数子类化;只有一个班级
  • 如果要使用子类,则需要threading.Thread,而不是threading.thread

如果您真的只想使用函数来执行此操作,则有两个选择:

使用线程:

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

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

带螺纹:

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

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

Thread.start_new_thread的文档


2
第二个参数必须是一个元组thread.start_new_thread(function, args[, kwargs])
venkatvb

14

我试图添加另一个join(),似乎可行。这是代码

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

您可以targetThread构造函数中使用参数直接传递被调用而不是的函数run


2

您是否覆盖了run()方法?如果您改写了__init__,您确定要呼叫基地threading.Thread.__init__()吗?

启动两个线程后,主线程是否继续在子线程上无限期地工作/阻塞/联接,以使主线程在子线程完成其任务之前不会结束执行?

最后,您是否遇到任何未处理的异常?


没有未处理的异常,主线程应运行30分钟。我没有重写__init__。然后需要run()吗?谢谢
chrisg 2010年

我只是意识到您的示例是def MyThread ( threading.thread )...我假设这些是类定义。如果要继承threading.thread的子类,并使用argtarget=None或不使用targetarg初始化线程对象,则需要run()的实现。否则,如果您只想在另一个线程中运行一个简单的任务,请参见jkp的答案。
杰里米·布朗

0

Python 3具有启动并行任务的功能。这使我们的工作更加轻松。

它具有线程池进程池

以下提供了一个见解:

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

另一个例子

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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.