三、python并发编程之多线程

一、线程理论:


1、什么是线程?

  线程指的是一条流水线的工作过程。

  进程根本不是一个执行单位,进程其实是一个资源单位,一个进程内自带一个线程,线程才是执行单位。

2、进程VS线程:

  1)同一进程内的线程们共享该进程内资源

  2)不同进程内的线程资源肯定是隔离的。

  3)创建线程的开销比创建进程要小的多。

3、为何要用多线程?

  1)多线程共享一个进程的地址空间

  2)线程比进程更轻量级,线程比进程更容易创建,在许多操作系统中,创建一个线程比创建一个进程要快10-100倍,

在有大量线程需要动态和快速修改时,这一特性很有用。

  3)若是多个线程都是计算密集型,这时使用多线程并不能获得性能上的增强,但如果时 IO密集型时,则会加快程序的执行速度。

  4)在多cpu系统中,为了最大限度的利用多核,可以开启多个线程,比开进程开销要小的多。(但这一条并不使用于python)


二、线程的使用:

1、开启线程的两种方式

from threading imoprt Thread

开启线程的两种方式

 

 2、进程VS线程

  进程时一个资源单位

  线程才是真正的执行单位

  一个进程必须有至少一个线程

  1)PID

PID

  2)线程创建开销小

  3)同一个进程内的多个线程共享该进程内的资源

from  threading import Thread
import time
x=1000
def task():
    global x
    print(x)
    x=0
    time.sleep(1)
if __name__ == '__main__':
    t=Thread(target=task)  #线程开启速度比进程快
    t.start()
    # t.join()
    print('主进程。。',x)
线程开启速度比进程快

 

3、线程对象的其它方法

from  threading import Thread,current_thread,active_count,enumerate
import time
x=1000
def task(name):
    print('%s is runing'%name)
    time.sleep(3)

if __name__ == '__main__':
    t=Thread(target=task,args=('egon',))
    t.start()
    print(enumerate())  #查看线程
    print(active_count())  #查看有几个线程,主进程也是一个线程
    print('主进程。。',current_thread().name)   #查看主进程
View Code

 

4、守护线程

守护子线程,主线程结束则子进程结束,主线程需等到所有非守护子线程结束才结束
from  threading import Thread,current_thread,active_count,enumerate
import time
def task(name):
    print('%s is runing'%name)
    time.sleep(3)
    print('%s is runing' % name)



if __name__ == '__main__':
    t=Thread(target=task,args=('egon',))
    # t1 = Thread(target=task, args=('egon',))
    t.daemon=True           #守护子线程,主线程结束则子进程结束,主线程需等到所有非守护子线程结束才结束
    t.start()
    # t1.start()
    print('主进程。。')
View Code

 

5、线性互斥锁

from threading import  Thread,Lock
import time

x=100
mutex=Lock() #造一把锁

def task():
    global x
    # mutex.acquire()   #锁住变成串行
    temp=x
    time.sleep(0.1)
    x=temp-1
    # mutex.release()

if __name__ == '__main__':
    t_1=[]
    for i in range(100):
        t=Thread(target=task)
        t_1.append(t)
        t.start    ()

    for t in t_1:
        t.join()
    print('',x)  #不加锁,并行的速度很快都是x的值都是100
View Code
 

 6、死锁与递归锁

from threading import  Thread,Lock,RLock
import time

# mutexA=Lock()
# mutexB=Lock()
mutexA=mutexB=RLock()
class MyThread(Thread):
    def run(self):
        self.f1()
        self.f2()

    def f1(self):
        mutexA.acquire()
        print('%s 拿到了A锁' %self.name)

        mutexB.acquire()
        print('%s 拿到了B锁' %self.name)
        mutexB.release()

        mutexA.release()

    def f2(self):
        mutexB.acquire()
        print('%s 拿到了B锁' %self.name)
        time.sleep(0.1)

        mutexA.acquire()
        print('%s 拿到了A锁' %self.name)
        mutexA.release()

        mutexB.release()


if __name__ == '__main__':
    for i in range(10):
        t=MyThread()
        t.start()

    # t1=MyThread()
    # t1.start()
    #
    # t2=MyThread()
    # t2.start()
    #
    # t3=MyThread()
    # t3.start()
    print('')
View Code

 

 7、信号量

from threading import Thread,Semaphore,current_thread
import time,random

sm=Semaphore(5)    #一次只放五个位置

def go_wc():
    sm.acquire()
    print('%s 上厕所ing' %current_thread().getName())
    time.sleep(random.randint(1,3))
    sm.release()

if __name__ == '__main__':
    for i in range(23):
        t=Thread(target=go_wc)
        t.start()
View Code

 

posted @ 2018-04-27 15:52  CLuke  阅读(157)  评论(0)    收藏  举报
Live2D