多线程与多进程---方法对比与使用

Posted Twotigers

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程与多进程---方法对比与使用相关的知识,希望对你有一定的参考价值。

多线程与多进程

 

  1. 创建多线程和多进程
    1. 创建多线程

      方法一: 直接调用

    2. import threading, time  
    3.     
    4.     
    5. def foo(name):  
    6.     time.sleep(1)  
    7.     print("foo", name)  
    8.     
    9.     
    10. if __name__ == \'__main__\':  
    11.     print("开始")  
    12.     th = threading.Thread(target=foo, args=("test",))  
    13.     th.start()  
    14.     th.join()  
    15.     print("end")  
    16.  

       

      方法二:继承式调用

  2. import threading, time  
    1.     
    2.     
    3. class Foo(threading.Thread):  
    4.     def __init__(self, name):  
    5.         super().__init__()  #注意,这一行必须有,没有则会报错
    6.         self.name = name  
    7.     
    8.     def run(self):  
    9.         time.sleep(1)  
    10.         print("foo", self.name)  
    11.     
    12.     
    13. if __name__ == \'__main__\':  
    14.     print("开始")  
    15.     f = Foo("test")  
    16.     f.start()  
    17.     f.join()  
    18.     print("end")  
    1. 创建多进程

      方法一:直接调用

    2. # coding=utf-8  
    3. import multiprocessing, time, os  
    4.     
    5.     
    6. def foo(name):  
    7.     time.sleep(1)  
    8.     print("foo", name, os.getpid())  
    9.     
    10.     
    11. if __name__ == \'__main__\':  
    12.     print("开始", os.getpid())  
    13.     mp = multiprocessing.Process(target=foo, args=("test",))  
    14.     mp.start()  
    15.     mp.join()  
    16.     print("end")  
    17.     输入结果:  
    18.     开始 10960  
    19.     # foo test 3884  
    20.     # end  

      注意: args=("test",)这里是一个元组,如果只有一个参数则必须在后面加上一个逗号

      windows 下必须需要加上if __name__ == \'__main__\': ,万恶的Windows

    21. 方法二:

    22. import multiprocessing, time, os  
    23.     
    24.     
    25. class Foo(multiprocessing.Process):  
    26.     def __init__(self, name):  
    27.         super().__init__()   #,没错还是这一行,没有的话会报错的
    28.         self.name = name  
    29.     
    30.     def run(self):  
    31.         time.sleep(1)  
    32.         print("foo", self.name, os.getpid())  
    33.     
    34.     
    35. if __name__ == \'__main__\':  
    36.     print("开始", os.getpid())  
    37.     f = Foo("test")  
    38.     f.start()  
    39.     f.join()  
    40.     print("end")  
    41. 输出结果:  
    42. 开始 1840  
    43. # foo test 8968  
    44. # end  
    45.  

  3. 进程与线程的一些方法:

1..进程:

    预先在Ipython中输入:

In [9]: import threading, time

...: class Foo(threading.Thread):

...: def __init__(self, age): #这里先将name换掉

...: super().__init__()

...: self.name = age

...: def run(self):

...: time.sleep(1)

...: print("foo", self.age)

In [10]: f = Foo("test")

这里是为什么暂时先不用name,

这里使用name,则线程名就是传入的

方法

 

getName()

name

得到线程名

In [16]: f.getName()

Out[16]: \'Thread-937\'

In [17]: f.name

Out[17]: \'Thread-937\' 

setName()

给线程设置线程名

In [17]: f.setName("jjjj")

In [18]: f.getName()

Out[18]: \'jjjj\'

is_alive()

是否是活动线程

/

isDaemon()

setDaemon() 

设置setDaemon为true时,执行完后,主进程没有执行完会阻塞,主进程先执行完,则子进程会在主进程执行完之后KILL掉

In [10]: f.setDaemon(True)

In [11]: f.isDaemon()

Out[11]: True 

join(time)

等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生

/

start()

启动线程活动。

/

daemon

f.daemon=True

设置或获得daemon

/

三个threading的方法

threading.enumerate()

返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

In [27]: threading.enumerate()

Out[27]:

[<HistorySavingThread(IPythonHistorySavingThread, started 5048)>,

<_MainThread(MainThread, started 4028)>]

threading.activeCount() 

返回正在运行的线程数量,与len(threading.enumerate())有相同的结果

In [31]: threading.activeCount()

Out[31]: 2 

threading.currentThread()

返回当前的线程变量。

In [32]: threading.current_thread()

Out[32]: <_MainThread(MainThread, started 4028)> 

2 进程

is_alive()

是否是活动进程

/

join()

阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。

/

start()

进程准备就绪,等待CPU调度

/

daemon

同线程

In [13]: f.daemon=True

In [14]: f.daemon

Out[14]: True

name

命名

In [20]: f.name="123412"

 

In [21]: f.name

Out[21]: \'123412\'

pid

等于 os.getpid()

/

terminate()

不管任务是否完成,立即停止工作进程

/

  1. 1线程.

    1. 同步锁: threading.Lock()

lock = threading.Lock() #创建一个线程锁对象

lock.acquire() #加锁,并且返回一个布尔类型, 不可多次acquire,会阻塞住

lock.release() #去锁,返回值为NONE

 

 

  1. 死锁,和递归锁

在同时存在两个或者多个锁对象的时候,可能就会出现死锁现象.可以使用递归锁解决该问题.

rlock =threading.RLock()

rlock.acquire() #可以多次, acquire

rlock.release() #几次acquire,几次acquire

 

  1. 信号量

这个类似于停车场,车位是一定数量的,当停满后,外面的车只能在外面等待,线程无法拿到锁,不能执行

lock=threading.BoundedSemaphore(4) #创建一个信号量对象,允许同时有4个线程可以拿到锁,其他的线程需要等有线程去锁后才可以拿到

 

2进程.

注意:进程之间是无法直接共享数据的,所以在父进程创建的锁对象,是无法在子进程中使用的.so,要么在子进程中创建锁,要么直接给他传入一个锁对象(这样就能共享数据了)

代码如下:

import multiprocessing, time, os

 

class Foo(multiprocessing.Process):

def __init__(self, name, lock):

super().__init__()

self.name = name

self.lock = lock

 

def run(self):

self.lock.acquire()

time.sleep(1)

print("foo", self.name, os.getpid())

 

print(self.pid)0

print(self.is_alive())

self.lock.release()

# print(self.g)

 

 

if __name__ == \'__main__\':

lock = multiprocessing.Lock()

print("开始", os.getpid())

f = Foo("test", lock)

# f.daemon=True

f.start()

f.join()

print("end")

 

 

或者使用内部创建一个锁,下面为Lock 还有Rlock

 

import multiprocessing, time, os

 

 

class Foo(multiprocessing.Process):

def __init__(self, name):

super().__init__()

self.name = name

#在内部创建一个锁对象,并且绑定到self

self.lock = multiprocessing.Lock()

 

def run(self):

self.lock.acquire()

time.sleep(1)

print("foo", self.name, os.getpid())

 

print(self.pid)

print(self.is_alive())

self.lock.release()

以上是关于多线程与多进程---方法对比与使用的主要内容,如果未能解决你的问题,请参考以下文章

Python多线程与多进程

Python多进程与多线程

多线程与多进程

python多进程与多线程使用场景

多线程与多进程的实现

python之多线程与多进程

(c)2006-2024 SYSTEM All Rights Reserved IT常识