1、线程

    线程被称为轻量级进程,是最小执行单元,系统调度的单位。线程切换需要的资源一般,效率一般。 

2、多线程

        在单个程序中同时运行多个线程完成不同的工作,称为多线程

3、并发:

    操作系统同时执行几个程序,这几个程序都由一个cpu处理,但在一个时刻点上只有一个程序在cpu上处理

4、并行:

    操作系统同时执行2个程序,但是有两个cpu,每个cpu处理一个程序,叫并行

5、串行:

    是指的我们从事某项工作是一个步骤一个步骤去实施 
 

一、多线程

#python3是假的多线程,它不是真真正正的并行,其实就是串行,只不过利用了cpu上下文的切换而已
 1 mport threading
2 import time
3 # def test1():
4 # for i in range(10):
5 # time.sleep(1) #睡1s
6 # print('test1=========>%s' % i)
7 #
8 #
9 # def test2():
10 # for i in range(10):
11 # time.sleep(1)
12 # print('test2=========>%s' % i)
13 #
14 # t1 = threading.Thread(target=test1) #定义一个线程 target=函数名
15 # t2 = threading.Thread(target=test2)
16 # t1.start() #开启线程
17 # t2.start()
18 # test1()
19 # test2()

# 多线程是无序的,并发的
因为在启动一个线程时,线程不会立即执行,而是等待cpu的资源调度。
1 # def test1(n):
2 # time.sleep(1)
3 # print('task', n)
4 # for i in range(10):
5 # t = threading.Thread(target=test1,args=('t-%s' % i,)) #args= 后接输出结果 末尾必须加 “ , ” 号
6 # t.start()
 
#计算并发所用的时间
 1
2 # import threading
3 # import time
4 # def dest(n):
5 # time.sleep(1)
6 # print('this is running====>%s' %n)
7 # l = [] #定义一个空列表
8 # start = time.time() #开始的时间
9 # for i in range(10): #10个进程
10 # t = threading.Thread(target=dest,args=(i,))
11 # t.start()
12 # l.append(t) #把线程执行时间加入到列表
13 # for g in l:
14 # g.join() #等待全部线程执行完毕
15 # end = time.time() #执行结束时间
16 # print('time',(end-start)) #执行结束时间 - 开始执行的时间
 
 1 import threading
2 import time
3 def test1(n):
4 time.sleep(1)
5 print('test1====>%s' %n)
6 def test2(n):
7 time.sleep(2)
8 print('test2====>%s' %n)
9 start = time.time()
10 l = []
11 t1 = threading.Thread(target=test1,args=(1,))
12 t2 = threading.Thread(target=test2,args=(2,))
13 t1.start()
14 t2.start()
15 l.append(t1)
16 l.append(t2)
17 for i in l:
18 i.join()
19 end = time.time()
20 print('time',(end - start))
 
#多线程共享全局变量
 1 # g_num = 0
2 # def update():
3 # global g_num #global声明全局变量
4 # for i in range(10):
5 # g_num += 1
6 #
7 # def reader():
8 # global g_num
9 # print(g_num)
10 #
11 # t1 = threading.Thread(target=update)
12 # t2 = threading.Thread(target=reader)
13 # t1.start()
14 # t2.start()
15

二、GIL全局解释器锁

        只有获得GIL锁的线程才能真正在cpu上运行。所以,多线程在python中只能交替执行,即使100个线程跑在100核cpu上,也只能用到1核。
 1
2 # import threading
3 # global_num = 0
4 # def test1():
5 # global global_num #global声明全局变量
6 # for i in range(1000000):
7 # global_num += 1
8 # print("test1", global_num,threading.current_thread())
9 #
10 # def test2():
11 # global global_num
12 # for i in range(1000000):
13 # global_num += 1
14 # print("test2", global_num,threading.current_thread())
15 # t1 = threading.Thread(target=test1)
16 # t2 = threading.Thread(target=test2)
17 # t1.start()
18 # t2.start()
19 # print(global_num)
结果说明:每次执行结果都不一样,原因是python从上往下执行,主线程走的快,当主线程走到最后print打印结果的时候,test1 test2的count++还在继续执行,所以第一行打印出来的是它们在执行count++过程中的某一个值,至于test1和test2的值不是100w和200w,因为cpu没有足够的时间去进行count++就释放锁提交了
 

#互斥锁

以上出现的结果是随机的,并非我们想要的,所以要加入互斥锁。
互斥锁:
常用来防止两个进程或线程同一时刻访问相同的共享资源, 如果一个线程锁定了一个互斥量,在它解除锁定之前没有其他线程可以锁定这个互斥量。
 1 import threading
2 import time
3 global_num = 0
4
5 lock = threading.Lock() #互斥锁
6
7 def test1():
8 global global_num
9 lock.acquire()
10 for i in range(1000000):
11 global_num += 1
12 lock.release()
13 print("test1", global_num)
14
15
16 def test2():
17 global global_num
18 lock.acquire()
19 for i in range(1000000):
20 global_num += 1
21 lock.release()
22 print("test2", global_num)
23
24 t1 = threading.Thread(target=test1)
25 t2 = threading.Thread(target=test2)
26 start_time = time.time()
27
28 t1.start()
29 t2.start()
30 t1.join()
31 t2.join()
32 print(global_num)
加上互斥锁之后,test1线程执行完才释放锁提交,让test2线程拿到共享资源继续执行,要想结果是200w,就必须是主线程等子线程执行完之后才执行print。
 
#只要在进行耗时的IO操作的时候,能释放GIL,所以只要在IO密集型的代码里,用多线程就很合适
 

最新文章

  1. curl操作CouchDB
  2. undefined reference to `libiconv_open 无法编译PHP
  3. 发布mvc遇到的HTTP错误 403.14-Forbidden解决办法
  4. 【poj1013】 Counterfeit Dollar
  5. Visual Studio Professional 2015 key
  6. sizeof()用法汇总
  7. UOJ150 运输计划
  8. Linux常用命令_(文件操作)
  9. IEqualityComparer<T>接口
  10. 推荐五个最好的MySQL GUI工具
  11. 经典排序算法 - 基数排序Radix sort
  12. windows10上pip install channels
  13. JavaJDK8新特性相关知识整理
  14. Elastic Stack之FileBeat使用实战
  15. Docker 推送镜像到hub.docker
  16. 【转】css3实现文字闪烁,改变透明度
  17. Python这么热,要不要追赶Python学习热潮?
  18. windows 激活venv问题
  19. linux suse 同步时间
  20. C#中转义字符[转]

热门文章

  1. DRF终极封装ViewSet和Router附教程PDF源码
  2. 仙剑4CPK加密解密算法(转)
  3. C#访问Access数据库提示未安装ISAM
  4. JVM初始化类契机
  5. 详细介绍如何自研一款"博客搬家"功能
  6. Ubuntu/Liinux睡眠无法唤醒解决方法:ACPI设置
  7. Docker PHP 扩展配置
  8. 剑指offer 面试题0:高质的代码:即考虑边界条件、特殊输入和错误处理
  9. Spring MVC 接收 LocalDate、LocalTime 和 LocalDateTime Java 8 时间类型参数
  10. 深入剖析setState同步异步机制