python基础学习20----线程

python基础学习20----线程,第1张

概述什么是线程 线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中

Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。线程是程序中一个单一的顺序控制流程。进程内有一个相对独立的、可调度的执行单元,是系统独立调度和分派cpu的基本单位指令运行时的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

  进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是 *** 作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

<span >def<span > func(msg):
<span >print<span >(msg)
<span >print(<span >"<span >这是一个线程<span >"<span >)

t=threading.Thread(target=func,args=(<span >"<span >hello world<span >"<span >,))
t.start()

通过继承类的方式创建线程

==</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;<a href="https://m.jb51.cc/tag/zheli/" target="_blank" >这里</a>是将threading.Thread中的run<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a><a href="https://m.jb51.cc/tag/jinxing/" target="_blank" >进行</a>了重载</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;<a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> is %d</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span>%<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>,self.age))

t=Mythread(<span >"<span >sfencs<span >",19<span >)
t.start()

2.线程的并发

单个线程的创建基本没有意义,只是与主线程并发,现在我们看一下多个线程的并发

===</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>) time.sleep(self.second) </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self.age)

t1=Mythread(<span >"<span >sfencs<span >",19,2<span >)
t2=Mythread(<span >"<span >Tom<span >",25,5<span >)
t1.start()
t2.start()

这里先同时打印sfencs和Tom,过了两秒打印19,又过3秒打印25.这说明这两个线程是并发的,如果是串行的那么会使用7秒完成

我们可以使用time模块计算时间

===</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>) time.sleep(self.second) </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self.age)

time_begin=<span >time.time()

t1=Mythread(<span >"<span >sfencs<span >",5<span >)
t1.start()
t2.start()
time_end=<span >time.time()
<span >print(time_end-time_begin)
'''

sfencsTom0.00103068351745605471925

'''

这里出现一个问题,输出的时间是0.0010306835174560547,而且在年龄之前输出的

原因是计算时间的代码属于主线程,它与两个自己创建的线程并发,所以它提前完成了计算,为了解决这个办法,我们使用join()方法

3.join()

time_begin=t1=Mythread(<span >"
<span >sfencs
<span >"
,5<span >)
t1.start()
t2.start()
t1.join()
t2.join()
time_end
=<span >time.time()
<span >print
(time_end-<span >time_begin)
<span >'''
<span >
sfencs
Tom
19
25
5.001618146896362
<span >'''

这样就显然的看出程序并发节约了约2秒钟

除此之外join()方法还有一个参数为阻塞的时间,默认为一直阻塞

4.IO密集型任务和计算密集型任务

IO密集型任务就如上述的例子一样,有阻塞的状态,如sleep()或者等待相关信息,信号时会停用cpu的任务。IO密集型的任务在python中使用多线程能够很好的节约时间完成并发。

计算密集型任务没有等待状态,从上到下执行,没有任何等待

一个线程

</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self): i</span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;0 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;while</span> i<100000000<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;: i</span>+=1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;

time_begin=<span >time.time()
t1=<span >Mythread()
t1.start()
t1.join()
time_end=<span >time.time()
<span >print(time_end-time_begin)#6.194466590881348

两个线程

</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self): i</span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;0 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;while</span> i<100000000<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;: i</span>+=1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;

time_begin=<span >time.time()
t1=<span >Mythread()
t2=<span >Mythread()
t1.start()
t2.start()
t1.join()
t2.join()
time_end=<span >time.time()
<span >print(time_end-time_begin)#11.998910427093506

可见计算密集型任务在python中并发并不能很好的节约时间,和串行差不多(在python以前版本中时间还会比串行多)

可是又有一个问题,我们的电脑不是有多核cpu吗,为什么不能同时两个cpu每个运行一个线程,那样时间就只有串行的一半啊?原因就是接下来讲的GIL

5.GIL

  首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(cpython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过cpython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为cpython是大部分环境下默认的Python执行环境。所以在很多人的概念里cpython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。

那么cpython实现中的GIL又是什么呢?GIL全称Global Interpreter Lock为了避免误导,我们还是来看一下官方给出的解释:

In cpython,the global interpreter lock,or GIL,is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because cpython’s memory management is not thread-safe. (However,since the GIL exists,other features have grown to depend on the guarantees that it enforces.)

 GIL就像是一个防止多线程并发的全局锁,GIL的存在导致多线程无法很好的立即多核cpu的并发处理能力。python的多线程在多核cpu上,只对于IO密集型计算产生正面效果;而当有至少有一个cpu密集型线程存在,那么多线程效率会由于GIL而大幅下降。为了避免GIL的影响,可以使用多进程。

这里具体参考href="https://www.cnblogs.com/SuKiWX/p/8804974.HTML" target="_blank">https://www.cnblogs.com/SuKiWX/p/8804974.HTML

6.守护线程setDaemon

当主线程完成时不需要某个子线程完全运行完就要退出程序,那么就可以将这个子线程设置为守护线程,setDaemon(True).

=(time_end-

不会显示年龄的输出,因为主线程已经结束。

7.Lock锁

多线程中对同一资源进行处理,有可能会导致数据不安全

<span >def<span > addNum():
<span >global
<span > num

</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;lock.acquire()</span>temp=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;numtime.sleep(</span>0.001<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)num </span>=temp-1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;lock.release()</span>

<span >
num = 100<span >
thread_List =<span > []
lock=<span >threading.Lock()

<span >for i <span >in range(100<span >):
t = threading.Thread(target=<span >addNum)
t.start()
thread_List.append(t)

<span >for t <span >in<span > thread_List:
t.join()

<span >print(<span >'<span >final num:<span >',num )#final num: 92

这里运行结果并不是0,原因是多个线程在time.sleep()的时候同时拿到了num,所以num是同一个数,解决方法就是加锁

8.死锁与递归锁

==<span >class<span > MyThread(threading.Thread):
<span >def
<span > run(self):
self.func1()
self.func2()
<span >def
<span > func1(self):
mutexA.acquire()
<span >print
(<span >'
<span >%s 拿到A锁
<span >'
%<span >self.name)
mutexB.acquire()
<span >print
(<span >'
<span >%s 拿到B锁
<span >'
%<span >self.name)
mutexB.release()
mutexA.release()

</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; func2(self):    mutexB.acquire()    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;<a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> 拿到B锁</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;'</span> %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)    time.sleep(</span>2<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)    mutexA.acquire()    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;<a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> 拿到A锁</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;'</span> %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)    mutexA.release()    mutexB.release()

<span >if <span >name == <span >'<span >main<span >'<span >:
<span >for i <span >in range(5<span >):
t=<span >MyThread()
t.start()'''

Thread-1 拿到A锁Thread-1 拿到B锁Thread-1 拿到B锁Thread-2 拿到A锁

 这里开了5个线程,可是却阻塞住了,原因是在Thread1拿到B锁,Thread2拿到A锁时,func2中在等待获得A锁,func1中在等待获得B锁,两者都在等待对方释放锁,造成了死锁,使得线程互相阻塞解决方法是使用递归锁Rlock

=<span >class<span > MyThread(threading.Thread):
<span >def
<span > run(self):
self.func1()
self.func2()
<span >def
<span > func1(self):
lock.acquire()
<span >print
(<span >'
<span >%s 拿到A锁
<span >'
%<span >self.name)
lock.acquire()
<span >print
(<span >'
<span >%s 拿到B锁
<span >'
%<span >self.name)
lock.release()
lock.release()

</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; func2(self):    lock.acquire()    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;<a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> 拿到B锁</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;'</span> %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)    time.sleep(</span>2<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)    lock.acquire()    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;<a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> 拿到A锁</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;'</span> %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)    lock.release()    lock.release()

<span >if <span >name == <span >'<span >main<span >'<span >:
<span >for i <span >in range(5<span >):
t=<span >MyThread()
t.start()
<span >'''<span >
Thread-1 拿到A锁
Thread-1 拿到B锁
Thread-1 拿到B锁
Thread-1 拿到A锁
Thread-2 拿到A锁
Thread-2 拿到B锁
Thread-2 拿到B锁
Thread-2 拿到A锁
Thread-4 拿到A锁
Thread-4 拿到B锁
Thread-4 拿到B锁
Thread-4 拿到A锁
Thread-3 拿到A锁
Thread-3 拿到B锁
Thread-3 拿到B锁
Thread-3 拿到A锁
Thread-5 拿到A锁
Thread-5 拿到B锁
Thread-5 拿到B锁
Thread-5 拿到A锁
<span >'''

在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。

这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源

9.信号量

<div >

=threading.Semaphore(3 ===</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self):    s.acquire()    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)    time.sleep(self.second)    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self.age)    s.release()

t=<span >[]
<span >for i <span >in range(6<span >):
t.append(Mythread(<span >"<span >sfencs<span >",2<span >))
time_begin=<span >time.time()
<span >for i <span >in range(6<span >):
t[i].start()
<span >for i <span >in range(6<span >):
t[i].join()
time_end=<span >time.time()
<span >print(time_end-<span >time_begin)
<span >'''<span >
sfencs
sfencs
sfencs
19
sfencs
19
sfencs
19
sfencs
19
1919

4.003796339035034
<span >'''

如果没有信号量来限制,那么程序完成的时间应该为2秒左右

10.条件变量同步

wait等待notify的通知,当接到通知后,会重新从if accquire()执行

== </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;global</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; count </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;while</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; True: </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; c.acquire(): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span> count>5<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;: c.wait() </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;: count</span>+=1 <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;:生产了一件商品</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;) c.notify() c.release() time.sleep(</span>0.5<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)

<span >class<span > consumer(threading.Thread):
<span >def <span >init<span >(self):
threading.Thread.<span >init<span >(self)

</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self):    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;global</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; count    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;while</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; True:        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; c.acquire():            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span> count<5<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;:                </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;:我再等一会儿</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)                c.wait()            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;:                count</span>-=1                <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;:<a href="https://m.jb51.cc/tag/shiyong/" target="_blank" >使用</a>了一件商品</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)                c.notify()            c.release()            time.sleep(</span>0.5<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)

<span >for i <span >in range(2<span >):
producer().start()
<span >for i <span >in range(5<span >):
consumer().start()

11.event

事件(event)用于线程间同步和通信。比如线程A要完成某一任务(event)线程B才能执行后面的代码

set()  开始一个事件

wait()  如果未设置set状态会一直等待,否则过

clear() 清除set状态

isSet() 是否设置set状态

<span >class<span > intervIEwer(threading.Thread):
<span >def
<span >init
<span >(self):

    threading.Thread.</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;<a href="https://www.jb51.cc/tag/init/" target="_blank" >__init__</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self)</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self):    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;我能问你<a href="https://www.jb51.cc/tag/yige/" target="_blank" >一个</a><a href="https://m.jb51.cc/tag/wenti/" target="_blank" >问题</a>吗?</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)    event1.set()    event2.wait()    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;我的<a href="https://m.jb51.cc/tag/wenti/" target="_blank" >问题</a>刚才已经问完了</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)    event2.clear()    event1.set()

<span >class<span > intervIEwee1(threading.Thread):
<span >def <span >init<span >(self):

    threading.Thread.</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;<a href="https://www.jb51.cc/tag/init/" target="_blank" >__init__</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(self)</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self):    event1.wait()    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;你问吧</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)    event1.clear()    event2.set()    event1.wait()    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;行吧。。。</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)    event1.clear()

event1=<span >threading.Event()
event2=<span >threading.Event()

t1 =<span > intervIEwee1()
t2 =<span > intervIEwer()
t1.start()
t2.start()'''

我能问你一个问题吗?你问吧我的问题刚才已经问完了行吧。。。

12.队列queue

说道多线程就不得不提到队列,python中的队列用到了Queue模块,该模块提供了同步的,安全的对序列,包括FIFO(先入先出)队列Queue,liFO(后入先出)队列lifoQueue,和优先级队列PriorityQueue.这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的通信

Queue.qsize() 返回队列的大小

Queue.empty() 如果队列为空,返回True,反之False

Queue.full 与 maxsize 大小对应

Queue.get([block[,timeout]])获取队列,timeout等待时间

Queue.get_Nowait() 相当Queue.get(False)

Queue.put(item) 写入队列,timeout等待时间

Queue.put_Nowait(item) 相当Queue.put(item,False)

Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号

Queue.join() 实际上意味着等到队列为空,再执行别的 *** 作

这个程序将之前的一个用队列改写的

== </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;global</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; count </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;while</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; True: </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; c.acquire(): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; count.f<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l(): c.wait() </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;: count.put(</span>1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;) </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;:生产了一件商品</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;) c.notify() c.release() time.sleep(</span>0.5<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)

<span >class<span > consumer(threading.Thread):
<span >def <span >init<span >(self):
threading.Thread.<span >init<span >(self)

</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; run(self):    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;global</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; count    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;while</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; True:        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; c.acquire():            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;not</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; count.f<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l():                </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;:我再等一会儿</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)                c.wait()            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;:                count.get()                </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;print</span>(self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;:<a href="https://m.jb51.cc/tag/shiyong/" target="_blank" >使用</a>了一件商品</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)                c.notify()            c.release()            time.sleep(</span>0.5<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)

<span >for i <span >in range(2<span >):
producer().start()
<span >for i <span >in range(5<span >):
consumer().start()

总结

以上是内存溢出为你收集整理的python基础学习20----线程全部内容,希望文章能够帮你解决python基础学习20----线程所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1208202.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存