cpython 多线程_Python “多线程”及其适用范围和缺点

Python多线程的一些理解:

1.多线程采用的是分时复用技术,即不存在真正的多线程,cpu做的事是快速地切换线程,以达到类似同步运行的目的(对于多核CPU可实现真正的多线程);

2.多线程对于计算密集型程序没有用,因为计算计算密集型程序没有等待,是连续计算的,但对I/O密集型程序(延迟IO,网络等)有用,因为这类程序有等待,等待时就可以切换其他线程,避免浪费时间。

3.原子操作:最小的操作步骤,这件事情是不可再分的,如变量的赋值,不可能一个线程在赋值,到一半切到另外一个线程工作去了……但是一些数据结构的操作,如栈的push什么的,并非是原子操作,比如要经过栈顶指针上移、赋值、计数器加1等等,在其中的任何一步中断,切换到另一线程再操作这个栈时,就会产生严重的问题,因此要使用锁来避免这样的情况。比如加锁后的push操作就可以认为是原子的了……

4.阻塞:所谓阻塞,就是只执行某些线程,而让其他线程等待,等待的线程就是被阻塞的线程,一直到这些线程执行结束。最简单的例子就是某一线程在原子操作下,则其它线程都是阻塞状态,这是微观的情况。对于宏观的情况,比如服务器等待用户连接,如果始终没有连接,那么这个线程就在阻塞状态。同理,最简单的input语句,在等待输入时也是阻塞状态。

5.在创建线程后,如果只执行t.start(),则这个线程t是非阻塞的,即主线程会继续执行其他的指令,相当于主线程和子线程都并行地执行。t.start()后,若启动t.join(),则t就是阻塞的,即只有当t结束后才执行其他指令。

#该段函数是后面所有函数的公共部分,定义了猫和狗的叫声

import threading, time

def cat(num): #猫叫

print('cat_start:' + time.strftime('%H:%M:%S'))

for i in range(num):

print(" cat:喵 "+ time.strftime('%H:%M:%S'))

time.sleep(1)

print('cat_stop:' + time.strftime('%H:%M:%S'))

def dog(num): #狗叫

print('dog_start:' + time.strftime('%H:%M:%S'))

for i in range(num):

print(" dog:汪 "+ time.strftime('%H:%M:%S'))

time.sleep(1)

print('dog_stop:' + time.strftime('%H:%M:%S'))

上面程序定义了猫和狗的叫声。

#case 1

if __name__ == "__main__":

cat(3)

dog(3)

print('print:'+ time.strftime('%H:%M:%S'))

输出:

cat_start:14:17:34

cat:喵 14:17:34

cat:喵 14:17:35

cat:喵 14:17:36

cat_stop:14:17:37

dog_start:14:17:37

dog:汪 14:17:37

dog:汪 14:17:38

dog:汪 14:17:39

dog_stop:14:17:40

Over:14:17:40

上述程序按常规方法执行猫和狗的叫声,根据时间可以看出,完全是顺序执行的,即先猫叫,再狗叫,最后是print()。总时间为:16s

#case 2

if __name__ == "__main__":

thread1 = threading.Thread(target = cat,args=(3,)) #让第一个线程执行“猫叫”

thread1.start() #启动猫叫线程

thread2 = threading.Thread(target = dog,args=(3,)) #让第二个线程执行“狗叫”

thread2.start() #启动狗叫线程

print('over:'+ time.strftime('%H:%M:%S'))

输出:

cat_start:14:26:22

cat:喵 14:26:22

dog_start:14:26:22

dog:汪 14:26:22

over:14:26:22

cat:喵 14:26:23

dog:汪 14:26:23

cat:喵 14:26:24

dog:汪 14:26:24

cat_stop:14:26:25

dog_stop:14:26:25

上述程序利用“多线程”的方式执行程序,从结果可以看出,猫、狗、print()三者在14:26:22时刻几乎同时启动,即几乎是并行执行,总耗时只要:3s,相比于前面的常规方法,节省了大量时间。

注意:

(1) x.start()是必须的,否则线程不会启动。

(2) 虽然从代码位置而言,thread1、th

你可能感兴趣的:(cpython,多线程)