ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

advPython-1

2026/8/16 5:57:13 拓冰建站 浏览量
advPython-1

创建进程

"""
创建进程(最快创建进程的方式是双击应用程序)
""""""
基础知识:
1.进程具有三种基本状态(就绪,执行,阻塞)创建--(提交)--就绪--(进程调度)--运行--(释放)--终止|<——   阻塞    <——|2.
同步和异步(程序里面)
阻塞和非阻塞(进程调度问题)3.查看进程号(pid号)
---A.通过 os模块:os.getpid()
---A.通过 multiprocessing模块中的 current_process:current_process().pid"""from multiprocessing import Process, current_process
import time
import osdef task(name):print(name, "正在进行中...")print(name, "的进程号为--->", os.getpid())print(f"进程号>>>{current_process().pid}\n")time.sleep(3)print(name, "已结束任务")if __name__ == '__main__':# 创建两个进程对象p1 = Process(target=task, args=("子进程--p1",))p2 = Process(target=task, args=("子进程--p2",))# 开始进程p1.start()p2.start()# 向操作系统发起请求:杀死p1进程(win:taskkill pid)p1.terminate()time.sleep(0.01)# 判断p1进程是否存在print(p1.is_alive())# 等待p2进程结束p2.join()  # join方法:让主进程等待子进程运行结束之后再继续执行# 展示主进程print("\n我是主进程")print('"主进程"的进程号为>>>', os.getpid())

守护进程

"""
守护进程
"""
from multiprocessing import Process
import timedef task(name):print(f"{name},还活着")time.sleep(3)print(f"{name}正常死亡")if __name__ == '__main__':# 创建进程p = Process(target=task, kwargs={"name": "苏妲己"})# 设置进程的"守护进程"功能,将其设置为开启状态p.daemon = True  # 我活你活,我死你死(守护进程)# 开始进程p.start()# 主进程time.sleep(1)print("纣王驾崩了")

进程互斥锁

"""
互斥锁(购票案例)
"""
from multiprocessing import Process, Lock
import time
import json
import random"""
关于本文使用json模块的知识补充:
是的,json.dump() 和 json.load() 是互补的。
json.dump() 用于将 Python 对象转换为 JSON 格式并写入文件或类文件对象,
而 json.load() 用于将文件或类文件对象中的 JSON 格式数据读入并转换为 Python 对象。
这两个函数一起可以实现将 Python 对象序列化为 JSON 格式,再将其反序列化为 Python 对象
"""# 查票功能
def search_ticket(name):# 读取文件,查看当前车票数量with open("date/mutex_date", "rt", encoding="utf-8") as f:dic = json.load(f)print(f"用户{name}查询车票:{dic.get('ticket_num')}张")# 购票功能
def buy_ticket(name):# 查看当前票数with open("date/mutex_date", "rt", encoding="utf-8") as f:dic = json.load(f)# 模拟网络延迟time.sleep(random.randint(1, 5))# 进行购票if dic["ticket_num"] > 0:dic["ticket_num"] -= 1with open("date/mutex_date", "wt", encoding="utf-8") as f:json.dump(dic, f)print(f"用户{name}购票成功")else:print(f"余票不足,用户{name}买票失败")# 查票或购票入口
def task(name, mutex):# 进行查票search_ticket(name)# 进行购票mutex.acquire()  # 加锁(抢锁)buy_ticket(name)mutex.release()  # 解锁(释放锁)if __name__ == '__main__':# 创造一把锁mutex = Lock()# 创建六个进程for i in range(1, 7):p = Process(target=task, args=(f"{i}号人员", mutex))p.start()  # 开始进程

消息队列

Queue 基本知识

"""
消息队列:Queue[用于 进程(线程) 之间的信息传递]
"""
from multiprocessing import Queue# 创建队列对象,并定义其容量
q = Queue(3)# 向队列对象里面放数据
q.put("a")
q.put("b")
q.put("c")# 判断队列是否为"满"
print("队列是否满了?", q.full())# 从队列里面取数据
v1 = q.get()
v2 = q.get()
v3 = q.get()# 判断队列是否为"空"
print("队列是否空了?", q.empty())# 展示取出的结果
print("队列结果[先进先出]>>>", v1, v2, v3)"""
总结:
q.put("a")
q.get()# 下面的东西,在多进程的条件下不够准确:
q.put_nowait("a")
q.put("a", timeout=3) # 超时的单位为"秒"
q.get_nowait()
q.get(timeout=3)
q.full()
q.empty()
"""# 对Queue的补充# import queue
# from multiprocessing import Queue# # 先进先出Queue
# q = queue.Queue()
# q.put()
# q.get()
# q.get(timeout=3)
# q.get_nowait()
# q.put_nowait()
# q.full()
# q.empty()# # 后进先出Queue
# q = queue.LifoQueue()  # last in first out
# q.put("a")
# q.put("b")
# q.put("c")
# print(q.get())# # 优先级Queue,(优先等级数字,数据)=>(1,date)优先级大于(2,date)
# q = queue.PriorityQueue()
# q.put((1, "a"))
# q.put((25, "b"))
# q.put((-1, "c"))
# print(q.get())
# print(q.get())

Queue 的实例一

"""
队列 Queue的实例一 --- 基础使用
"""
from multiprocessing import Process, Queuedef task1(q):# 向队列对象q中传入数据q.put("我是来自task1的王牌")def task2(q):print("task2开始任务")# 从队列对象中拿出数据print("消息>>>", q.get())print("task2开始任务")if __name__ == '__main__':# 创建队列对象qq = Queue()# 创建两个进程p1和p2p1 = Process(target=task1, args=(q,))p2 = Process(target=task2, args=(q,))# 开始进程p1.start()p2.start()

Queue 的实例二

"""
队列 Queue的实例二 --- 生产者和消费者模型
"""from multiprocessing import Process, Queue, JoinableQueue
import time
import random"""
JoinableQueue
在Queue的基础上多了一个计数器机制,每put一个数据,计数器就加一
每调用一次task_done,计数器就减一
当计数器为0的时候,就可以走q.join后面的代码
"""# 生产者
def producer(name, food, q):for i in range(8):time.sleep(random.randint(1, 4))print(f"{name}生产了{food}{i}")q.put(f"{food}{i}")# 消费者
def consumer(name, q):while True:food = q.get()  # 队列没有数值了,就阻塞在这time.sleep(random.randint(1, 4))print(f"{name}吃了{food}")q.task_done()  # 告诉队列,已经拿走了一个数据,并且已经处理完了if __name__ == '__main__':# 创建队列对象q = JoinableQueue()  # 比 q = Queue 多了一些功能,如计数# 创建两个生产者进程和两个消费者进程p1 = Process(target=producer, args=("中华小当家", "黄金炒饭", q))p2 = Process(target=producer, args=("神厨小福贵", "佛跳墙", q))c1 = Process(target=consumer, args=("八戒", q))c2 = Process(target=consumer, args=("悟空", q))# 开始生产者进程p1.start()p2.start()# 将消费者进程的"守护进程"功能开启c1.daemon = Truec2.daemon = True# 开始消费者的进程c1.start()c2.start()# 等待进程p1和p2运行完毕p1.join()p2.join()# 等待队列中所有的数据被取完,再继续往后执行q.join()

创建线程

"""
创建线程
(以及~~~线程间的数据共享)
"""
from threading import Thread  # 创建线程必备
from threading import current_thread, active_count
import os
import timedef task1():print("当前'线程'的名字>>>", current_thread().name)print(f"{current_thread().name}的进程号>>>", os.getpid())global ageage = age + 1print(f"{current_thread().name}的age>>>", age)def task2():print("当前'线程'的名字>>>", current_thread().name)print(f"{current_thread().name}的进程号>>>", os.getpid())age = 666  # 本来age=19,但它在自己的空间建立了个age=666print(f"{current_thread().name}的age>>>", age)if __name__ == '__main__':# 主线程的 ageage = 18# 创建线程对象t1 = Thread(target=task1)t2 = Thread(target=task2)# 开始线程t1.start()t2.start()# 等待两个线程执行完毕,才继续主线程t1.join()t2.join()# 子线程结束前,主线程不会结束,主线程结束意味着关闭"进程"及其里面的资源print("当前'线程'的名字>>>", current_thread().name)print(f"{current_thread().name}的进程号>>>", os.getpid())# 输入主线程的 ageprint(f"{current_thread().name}的age>>>", age)

守护线程

"""
守护线程
"""
from threading import Thread
import time"""
主线程运行完毕后,它不会立刻结束,要等待所有子线程运行完毕才会结束
因为主线程的结束,意味着主线程所在的"进程"结束了
"""def task(name):print(f"{name}还活着")time.sleep(3)print(f"{name}正常死亡")if __name__ == '__main__':# 创建线程对象t = Thread(target=task, args=("苏妲己",))# 将线程的"守护线程"功能开启t.daemon = True# 开启线程t.start()# 主线程print("纣王驾崩了")

线程互斥锁

"""
线程互斥锁
"""
import time
from threading import Thread, Lockdef task(mutex):global num# 加锁处理mutex.acquire()  # 枪锁temp = numtime.sleep(0.05)num = temp - 1mutex.release()  # 释放锁if __name__ == '__main__':# 主线程 numnum = 30# 创建一个锁mutex = Lock()# 创建线程l = []  # 获取30个线程对象for i in range(30):t = Thread(target=task, args=(mutex,))t.start()l.append(t)# 等待所有子线程执行完毕,才执行主线程for i in l:i.join()print("主线程的num>>>", num)

递归锁

"""
递归锁
"""
from threading import Thread, current_thread, RLockdef task1():mutex.acquire()  # 抢到锁1print(current_thread().name, "抢到锁1")mutex.acquire()  # 抢到锁2print(current_thread().name, "抢到锁2")mutex.release()  # 释放锁2print(current_thread().name, "释放锁2")mutex.release()  # 释放锁1print(current_thread().name, "释放锁1")# 执行函数 task2task2()def task2():mutex.acquire()  # 抢到锁1print(current_thread().name, "抢到锁1")mutex.acquire()  # 抢到锁2print(current_thread().name, "抢到锁2")mutex.release()  # 释放锁2print(current_thread().name, "释放锁2")mutex.release()  # 释放锁1print(current_thread().name, "释放锁1")if __name__ == '__main__':# 创建一个递归锁mutex = RLock()# 创建八个线程for i in range(8):t = Thread(target=task1)t.start()

信号量

"""
信号量
———————————————————————————————————————————
信号量(Semaphore)是一种用于多线程编程的同步手段,
它可以控制同时访问某个共享资源的线程数量。
———————————————————————————————————————————
如果此时有其他线程请求获取信号量,它们就必须等待,直到有足够的资源被释放。
"""from threading import Thread, Semaphore
import time
import randomdef task(name, sp):# 对"资源"进行访问限制(被限制的内容,最多被5个线程同时访问)sp.acquire()  # 资源限制开始print(f"{name}抢到了停车位")time.sleep(random.randint(3, 6))sp.release()  # 资源限制结束if __name__ == '__main__':# 创建信号量对象sp = Semaphore(5)  # 同时访问某个资源时,最多5个线程# 创建20个线程for i in range(20):t = Thread(target=task, args=(f"路人{i + 1}号", sp))t.start()

事件

"""
Event事件
"""
from threading import Thread, Event
import timedef bus():print("公交车即将到站")time.sleep(3)print("公交车到站了")event.set()def passenger(name):print(f"{name}正在等车")event.wait()print(f"{name}上车出发")if __name__ == '__main__':# 创建Event的对象event = Event()# 创建bus线程对象t = Thread(target=bus)t.start()  # 开始线程# 创建passenger线程对象for i in range(10):t = Thread(target=passenger, args=(f"乘客{i + 1}号",))t.start()  # 开始线程

线程池

"""
线程池(thread pool)
"""
from concurrent.futures import ThreadPoolExecutor
import timedef task(name):print(f"路人{name}号")time.sleep(1)return name + 10if __name__ == '__main__':# 创建线程池pool = ThreadPoolExecutor(5)  # 线程池中的"线程数"10个,永远是这十个线程,只是内容和对象变了# 往线程池中提交任务---"创建线程"(并非真正独立再建立一个新的线程)f_list = []for i in range(1, 31):future = pool.submit(task, i)  # 往线程池中提交任务,返回一个对象f_list.append(future)  # 把对象(地址)存起来pool.shutdown()  # 关闭线程池,等待线程池中所有任务运行完毕for i in f_list:  # 遍历对象# 获得对象的result方法的值,若此result方法没有结果,则阻塞此处,等待它所对应的线程的运行结果print("任务结果:", i.result())

进程池

"""
进程池(process pool)
"""
from concurrent.futures import ProcessPoolExecutor
import os
import timedef task(name):print(f"对象{name}号-----{os.getpid()}")time.sleep(3)return name + 10if __name__ == '__main__':# 创建进程池pool = ProcessPoolExecutor(3)  # 一但进程池中进程的数量定下来后,永远都是这些进程在运作# 运行30个进程,3个为一批,一批运行完后,再运行下一批,共运行10批。进程都是同样的那3个f_list = []for i in range(30):future = pool.submit(task, i)  # 往进程池中提交任务,返回一个对象,f_list.append(future)  # 把对象(地址)存起来for i in f_list:  # 遍历对象# 获得对象的result方法的值,若此result方法没有结果,则阻塞此处,等待它所对应的进程的运行结果print("任务结果:", i.result())

回调机制

"""
回调机制
"""
from concurrent.futures import ProcessPoolExecutor
import time
import osdef task(name):print(f"进程{name}号 ---> 进程号>>>{os.getpid()}")time.sleep(3)return name + 10def call_back(obj):print("返回的结果>>>", obj.result())if __name__ == '__main__':# 创建进程池pool = ProcessPoolExecutor(3)# 发送任务for i in range(1, 31):# 异步回调机制future = pool.submit(task, i).add_done_callback(call_back)

yield 进阶

# # 当函数有yield的时候,它已经是生成器函数了
# def f1():
#     yield "hello"
#     yield "world"
#
#
# g = f1()  # 调用生成器函数不会执行函数体内容,它会得到一个可迭代的生成器对象
# print(next(g))
# print(next(g))
#
# for i in f1():
#     print(i)
#
#
# def f2():
#     return [i for i in range(100)]
#
#
# def f3():
#     for i in range(100):
#         yield i
#
#
# res = f3()
#
#
# def f4():
#     res = yield "hello"
#     yield res
#
#
# g = f4()
# print(next(g))
# print(g.send("world"))# # yield from语句
# def f5():
#     for s in "abc":
#         yield s
#     for i in range(3):
#         yield i
#
#
# for i in f5():
#     print(i)
#
#
# def f6():
#     yield from "abc"
#     yield from range(3)
#
#
# for i in f6():
#     print(i)def sub():yield "a"yield "b"return "c"def link():res = yield from sub()print("结果>>>", res)g = link()
next(g)
next(g)
next(g)

协程

"""
协程:
也可以称为微线程,它是一种用户态内的上下文切换技术,简单说就是在单线程下实现并发效果
"""
import time"""
进程:资源单位
线程:执行单位
协程:程序员人为创造出来的,不存在(切换+保存)当程序遇到IO的时候,通过我们写的代码,让我们的代码自动完成切换
也就是我们通过代码来监听IO,一旦程序遇到IO,就在代码层面上自动切换,
给cpu的感觉是"咋回事,你这个程序没有IO操作?咋不让我歇会啊!!!"
"""# # 单线程下执行技术密集型
# # 串行计数:0.44606804847717285
# # 切换计数:0.7273049354553223
# def f1():
#     n = 0
#     for i in range(10000000):
#         n += 1
#         yield
#
#
# def f2():
#     g = f1()
#     n = 0
#     for i in range(10000000):
#         n += 1
#         next(g)
#
#
# start = time.time()
# f2()
# end = time.time()
# print(end - start)# 单线程下执行IO密集型
from gevent import monkeymonkey.patch_all()
from gevent import spawn  # spawn 有一定的问题,需要加上猴子补丁def da():for _ in range(3):print("哒")time.sleep(0.5)def mie():for _ in range(3):print("咩")time.sleep(2)def buyao():for _ in range(3):print("不要")time.sleep(5)start = time.time()
g1 = spawn(da)  # 异步提交任务---执行并监听da()函数,有IO操作就跳到其他代码运行
g2 = spawn(mie)
g3 = spawn(buyao)
g1.join()
g2.join()
g3.join()end = time.time()
print(end - start)  # 12.003057479858398   6.050061464309692