做直播网站找哪个网站,wordpress 目录配置,石景山网站建设推广,一建十个专业含金量排名本文从14大模块展示了python高级用的应用。分别有Linux命令#xff0c;多任务编程、网络编程、Http协议和静态Web编程、htmlcss、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。
全套md格式笔记和代码自…
本文从14大模块展示了python高级用的应用。分别有Linux命令多任务编程、网络编程、Http协议和静态Web编程、htmlcss、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。
全套md格式笔记和代码自取 请移步这里 共 14 章157 子模块总计 85313 字 进程的注意点
学习目标
能够说出进程的注意点 1. 进程的注意点介绍
进程之间不共享全局变量主进程会等待所有的子进程执行结束再结束
2. 进程之间不共享全局变量
import multiprocessing
import time# 定义全局变量g_list list()# 添加数据的任务def add_data():for i in range(5):g_list.append(i)print(add:, i)time.sleep(0.2)# 代码执行到此说明数据添加完成print(add_data:, g_list)def read_data():print(read_data, g_list)if __name__ __main__:# 创建添加数据的子进程add_data_process multiprocessing.Process(targetadd_data)# 创建读取数据的子进程read_data_process multiprocessing.Process(targetread_data)# 启动子进程执行对应的任务add_data_process.start()# 主进程等待添加数据的子进程执行完成以后程序再继续往下执行读取数据add_data_process.join()read_data_process.start()print(main:, g_list)# 总结: 多进程之间不共享全局变量执行结果:
add: 0
add: 1
add: 2
add: 3
add: 4
add_data: [0, 1, 2, 3, 4]
main: []
read_data []进程之间不共享全局变量的解释效果图: 3. 进程之间不共享全局变量的小结
创建子进程会对主进程资源进行拷贝也就是说子进程是主进程的一个副本好比是一对双胞胎之所以进程之间不共享全局变量是因为操作的不是同一个进程里面的全局变量只不过不同进程里面的全局变量名字相同而已。
4. 主进程会等待所有的子进程执行结束再结束
假如我们现在创建一个子进程这个子进程执行完大概需要2秒钟现在让主进程执行0.5秒钟就退出程序查看一下执行结果示例代码如下:
import multiprocessing
import time# 定义进程所需要执行的任务def task():for i in range(10):print(任务执行中...)time.sleep(0.2)if __name__ __main__:# 创建子进程sub_process multiprocessing.Process(targettask)sub_process.start()# 主进程延时0.5秒钟time.sleep(0.5)print(over)exit()# 总结 主进程会等待所有的子进程执行完成以后程序再退出执行结果:
任务执行中...
任务执行中...
任务执行中...
over
任务执行中...
任务执行中...
任务执行中...
任务执行中...
任务执行中...
任务执行中...
任务执行中...说明:
通过上面代码的执行结果我们可以得知: 主进程会等待所有的子进程执行结束再结束
假如我们就让主进程执行0.5秒钟子进程就销毁不再执行那怎么办呢?
我们可以设置守护主进程 或者 在主进程退出之前 让子进程销毁
守护主进程:
守护主进程就是主进程退出子进程销毁不再执行
子进程销毁:
子进程执行结束
保证主进程正常退出的示例代码:
import multiprocessing
import time# 定义进程所需要执行的任务def task():for i in range(10):print(任务执行中...)time.sleep(0.2)if __name__ __main__:# 创建子进程sub_process multiprocessing.Process(targettask)# 设置守护主进程主进程退出子进程直接销毁子进程的生命周期依赖与主进程# sub_process.daemon Truesub_process.start()time.sleep(0.5)print(over)# 让子进程销毁sub_process.terminate()exit()# 总结 主进程会等待所有的子进程执行完成以后程序再退出# 如果想要主进程退出子进程销毁可以设置守护主进程或者在主进程退出之前让子进程销毁执行结果:
任务执行中...
任务执行中...
任务执行中...
over5. 主进程会等待所有的子进程执行结束再结束的小结
为了保证子进程能够正常的运行主进程会等所有的子进程执行完成以后再销毁设置守护主进程的目的是主进程退出子进程销毁不让主进程再等待子进程去执行。设置守护主进程方式 子进程对象.daemon True销毁子进程方式 子进程对象.terminate()
线程
学习目标
能够知道线程的作用 1. 线程的介绍
在Python中想要实现多任务除了使用进程还可以使用线程来完成线程是实现多任务的另外一种方式。
2. 线程的概念
线程是进程中执行代码的一个分支每个执行分支线程要想工作执行代码需要cpu进行调度 也就是说线程是cpu调度的基本单位每个进程至少都有一个线程而这个线程就是我们通常说的主线程。
3. 线程的作用
多线程可以完成多任务
多线程效果图: 4. 小结
线程是Python程序中实现多任务的另外一种方式线程的执行需要cpu调度来完成。
多线程的使用
学习目标
能够使用多线程完成多任务 1. 导入线程模块 #导入线程模块import threading2. 线程类Thread参数说明
Thread([group [, target [, name [, args [, kwargs]]]]])
group: 线程组目前只能使用Nonetarget: 执行的目标任务名args: 以元组的方式给执行任务传参kwargs: 以字典方式给执行任务传参name: 线程名一般不用设置
3. 启动线程
启动线程使用start方法
4. 多线程完成多任务的代码
import threading
import time# 唱歌任务def sing():# 扩展 当前线程# print(sing当前执行的线程为, threading.current_thread())for i in range(3):print(正在唱歌...%d % i)time.sleep(1)# 跳舞任务def dance():# 扩展 当前线程# print(dance当前执行的线程为, threading.current_thread())for i in range(3):print(正在跳舞...%d % i)time.sleep(1)if __name__ __main__:# 扩展 当前线程# print(当前执行的线程为, threading.current_thread())# 创建唱歌的线程# target 线程执行的函数名sing_thread threading.Thread(targetsing)# 创建跳舞的线程dance_thread threading.Thread(targetdance)# 开启线程sing_thread.start()dance_thread.start()执行结果:
正在唱歌...0
正在跳舞...0
正在唱歌...1
正在跳舞...1
正在唱歌...2
正在跳舞...25. 小结 导入线程模块 import threading 创建子线程并指定执行的任务 sub_thread threading.Thread(target任务名) 启动线程执行任务 sub_thread.start()
线程执行带有参数的任务
学习目标
能够写出线程执行带有参数的任务 1. 线程执行带有参数的任务的介绍
前面我们使用线程执行的任务是没有参数的假如我们使用线程执行的任务带有参数如何给函数传参呢?
Thread类执行任务并给任务传参数有两种方式:
args 表示以元组的方式给执行任务传参kwargs 表示以字典方式给执行任务传参
2. args参数的使用
示例代码:
import threading
import time# 带有参数的任务def task(count):for i in range(count):print(任务执行中..)time.sleep(0.2)else:print(任务执行完成)if __name__ __main__:# 创建子线程# args: 以元组的方式给任务传入参数sub_thread threading.Thread(targettask, args(5,))sub_thread.start()执行结果:
任务执行中..
任务执行中..
任务执行中..
任务执行中..
任务执行中..
任务执行完成3. kwargs参数的使用
示例代码:
import threading
import time# 带有参数的任务def task(count):for i in range(count):print(任务执行中..)time.sleep(0.2)else:print(任务执行完成)if __name__ __main__:# 创建子线程# kwargs: 表示以字典方式传入参数sub_thread threading.Thread(targettask, kwargs{count: 3})sub_thread.start()执行结果:
任务执行中..
任务执行中..
任务执行中..
任务执行完成4. 小结 线程执行任务并传参有两种方式: 元组方式传参(args) 元组方式传参一定要和参数的顺序保持一致。字典方式传参(kwargs)字典方式传参字典中的key一定要和参数名保持一致。
线程的注意点
学习目标
能够说出线程的注意点 1. 线程的注意点介绍
线程之间执行是无序的主线程会等待所有的子线程执行结束再结束线程之间共享全局变量线程之间共享全局变量数据出现错误问题
2. 线程之间执行是无序的
import threading
import timedef task():time.sleep(1)print(当前线程:, threading.current_thread().name)if __name__ __main__:for _ in range(5):sub_thread threading.Thread(targettask)sub_thread.start()执行结果:
当前线程: Thread-1
当前线程: Thread-2
当前线程: Thread-4
当前线程: Thread-5
当前线程: Thread-3说明:
线程之间执行是无序的它是由cpu调度决定的 cpu调度哪个线程哪个线程就先执行没有调度的线程不能执行。进程之间执行也是无序的它是由操作系统调度决定的操作系统调度哪个进程哪个进程就先执行没有调度的进程不能执行。
3. 主线程会等待所有的子线程执行结束再结束
假如我们现在创建一个子线程这个子线程执行完大概需要2.5秒钟现在让主线程执行1秒钟就退出程序查看一下执行结果示例代码如下:
import threading
import time# 测试主线程是否会等待子线程执行完成以后程序再退出def show_info():for i in range(5):print(test:, i)time.sleep(0.5)if __name__ __main__:sub_thread threading.Thread(targetshow_info)sub_thread.start()# 主线程延时1秒time.sleep(1)print(over)执行结果:
test: 0
test: 1
over
test: 2
test: 3
test: 4说明:
通过上面代码的执行结果我们可以得知: 主线程会等待所有的子线程执行结束再结束
假如我们就让主线程执行1秒钟子线程就销毁不再执行那怎么办呢?
我们可以设置守护主线程
守护主线程:
守护主线程就是主线程退出子线程销毁不再执行
设置守护主线程有两种方式
threading.Thread(targetshow_info, daemonTrue)线程对象.setDaemon(True)
设置守护主线程的示例代码:
import threading
import time# 测试主线程是否会等待子线程执行完成以后程序再退出def show_info():for i in range(5):print(test:, i)time.sleep(0.5)if __name__ __main__:# 创建子线程守护主线程 # daemonTrue 守护主线程# 守护主线程方式1sub_thread threading.Thread(targetshow_info, daemonTrue)# 设置成为守护主线程主线程退出后子线程直接销毁不再执行子线程的代码# 守护主线程方式2# sub_thread.setDaemon(True)sub_thread.start()# 主线程延时1秒time.sleep(1)print(over)执行结果:
test: 0
test: 1
over3. 线程之间共享全局变量
需求:
定义一个列表类型的全局变量创建两个子线程分别执行向全局变量添加数据的任务和向全局变量读取数据的任务查看线程之间是否共享全局变量数据
import threading
import time# 定义全局变量my_list list()# 写入数据任务def write_data():for i in range(5):my_list.append(i)time.sleep(0.1)print(write_data:, my_list)# 读取数据任务def read_data():print(read_data:, my_list)if __name__ __main__:# 创建写入数据的线程write_thread threading.Thread(targetwrite_data)# 创建读取数据的线程read_thread threading.Thread(targetread_data)write_thread.start()# 延时# time.sleep(1)# 主线程等待写入线程执行完成以后代码在继续往下执行write_thread.join()print(开始读取数据啦)read_thread.start()执行结果:
write_data: [0, 1, 2, 3, 4]
开始读取数据啦
read_data: [0, 1, 2, 3, 4]4. 线程之间共享全局变量数据出现错误问题
需求:
定义两个函数实现循环100万次每循环一次给全局变量加1创建两个子线程执行对应的两个函数查看计算后的结果
import threading# 定义全局变量g_num 0# 循环一次给全局变量加1def sum_num1():for i in range(1000000):global g_numg_num 1print(sum1:, g_num)# 循环一次给全局变量加1def sum_num2():for i in range(1000000):global g_numg_num 1print(sum2:, g_num)if __name__ __main__:# 创建两个线程first_thread threading.Thread(targetsum_num1)second_thread threading.Thread(targetsum_num2)# 启动线程first_thread.start()# 启动线程second_thread.start()执行结果:
sum1: 1210949
sum2: 1496035注意点:
多线程同时对全局变量操作数据发生了错误
错误分析:
两个线程first_thread和second_thread都要对全局变量g_num(默认是0)进行加1运算但是由于是多线程同时操作有可能出现下面情况
在g_num0时first_thread取得g_num0。此时系统把first_thread调度为”sleeping”状态把second_thread转换为”running”状态t2也获得g_num0然后second_thread对得到的值进行加1并赋给g_num使得g_num1然后系统又把second_thread调度为”sleeping”把first_thread转为”running”。线程t1又把它之前得到的0加1后赋值给g_num。这样导致虽然first_thread和first_thread都对g_num加1但结果仍然是g_num1
全局变量数据错误的解决办法:
线程同步: 保证同一时刻只能有一个线程去操作全局变量 同步: 就是协同步调按预定的先后次序进行运行。如:你说完我再说, 好比现实生活中的对讲机
线程同步的方式:
线程等待(join)互斥锁
线程等待的示例代码:
import threading# 定义全局变量g_num 0# 循环1000000次每次给全局变量加1def sum_num1():for i in range(1000000):global g_numg_num 1print(sum1:, g_num)# 循环1000000次每次给全局变量加1def sum_num2():for i in range(1000000):global g_numg_num 1print(sum2:, g_num)if __name__ __main__:# 创建两个线程first_thread threading.Thread(targetsum_num1)second_thread threading.Thread(targetsum_num2)# 启动线程first_thread.start()# 主线程等待第一个线程执行完成以后代码再继续执行让其执行第二个线程# 线程同步 一个任务执行完成以后另外一个任务才能执行同一个时刻只有一个任务在执行first_thread.join()# 启动线程second_thread.start()执行结果:
sum1: 1000000
sum2: 20000005. 小结 线程执行执行是无序的 主线程默认会等待所有子线程执行结束再结束设置守护主线程的目的是主线程退出子线程销毁。 线程之间共享全局变量好处是可以对全局变量的数据进行共享。 线程之间共享全局变量可能会导致数据出现错误问题可以使用线程同步方式来解决这个问题。 线程等待(join)
互斥锁
学习目标
能够知道互斥锁的作用 1.互斥锁的概念
互斥锁: 对共享数据进行锁定保证同一时刻只能有一个线程去操作。
注意:
互斥锁是多个线程一起去抢抢到锁的线程先执行没有抢到锁的线程需要等待等互斥锁使用完释放后其它等待的线程再去抢这个锁。
为了更好的理解互斥锁请看下面的图: 3. 互斥锁的使用
threading模块中定义了Lock变量这个变量本质上是一个函数通过调用这个函数可以一把互斥锁。
互斥锁使用步骤: # 创建锁mutex threading.Lock()# 上锁mutex.acquire()...这里编写代码能保证同一时刻只能有一个线程去操作, 对共享数据进行锁定...# 释放锁mutex.release()注意点:
acquire和release方法之间的代码同一时刻只能有一个线程去操作如果在调用acquire方法的时候 其他线程已经使用了这个互斥锁那么此时acquire方法会堵塞直到这个互斥锁释放后才能再次上锁。
4. 使用互斥锁完成2个线程对同一个全局变量各加100万次的操作
import threading# 定义全局变量g_num 0# 创建全局互斥锁lock threading.Lock()# 循环一次给全局变量加1def sum_num1():# 上锁lock.acquire()for i in range(1000000):global g_numg_num 1print(sum1:, g_num)# 释放锁lock.release()# 循环一次给全局变量加1def sum_num2():# 上锁lock.acquire()for i in range(1000000):global g_numg_num 1print(sum2:, g_num)# 释放锁lock.release()if __name__ __main__:# 创建两个线程first_thread threading.Thread(targetsum_num1)second_thread threading.Thread(targetsum_num2)# 启动线程first_thread.start()second_thread.start()# 提示加上互斥锁那个线程抢到这个锁我们决定不了那线程抢到锁那个线程先执行没有抢到的线程需要等待# 加上互斥锁多任务瞬间变成单任务性能会下降也就是说同一时刻只能有一个线程去执行执行结果:
sum1: 1000000
sum2: 2000000说明:
通过执行结果可以地址互斥锁能够保证多个线程访问共享数据不会出现数据错误问题
5. 小结
互斥锁的作用就是保证同一时刻只能有一个线程去操作共享数据保证共享数据不会出现错误问题使用互斥锁的好处确保某段关键代码只能由一个线程从头到尾完整地去执行使用互斥锁会影响代码的执行效率多任务改成了单任务执行互斥锁如果没有使用好容易出现死锁的情况
未完待续 下一期下一章
全套笔记直接地址 请移步这里
reading.Lock()
循环一次给全局变量加1
def sum_num1(): # 上锁 lock.acquire() for i in range(1000000): global g_num g_num 1
print(sum1:, g_num)
# 释放锁
lock.release()循环一次给全局变量加1
def sum_num2(): # 上锁 lock.acquire() for i in range(1000000): global g_num g_num 1 print(“sum2:”, g_num) # 释放锁 lock.release()
if name ‘main’: # 创建两个线程 first_thread threading.Thread(targetsum_num1) second_thread threading.Thread(targetsum_num2) # 启动线程 first_thread.start() second_thread.start()
# 提示加上互斥锁那个线程抢到这个锁我们决定不了那线程抢到锁那个线程先执行没有抢到的线程需要等待
# 加上互斥锁多任务瞬间变成单任务性能会下降也就是说同一时刻只能有一个线程去执行**执行结果:**py
sum1: 1000000
sum2: 2000000说明:
通过执行结果可以地址互斥锁能够保证多个线程访问共享数据不会出现数据错误问题
5. 小结
互斥锁的作用就是保证同一时刻只能有一个线程去操作共享数据保证共享数据不会出现错误问题使用互斥锁的好处确保某段关键代码只能由一个线程从头到尾完整地去执行使用互斥锁会影响代码的执行效率多任务改成了单任务执行互斥锁如果没有使用好容易出现死锁的情况
未完待续 下一期下一章
全套笔记直接地址 请移步这里