如何开启进程
使用的是内置的模块:multiprocess from multiprocessing import Process def task(): with open('a.txt', 'w', encoding="utf8") as f: f.write('helloworld') # 开一个进程来执行task这个任务 # 如何开进程 """在Windows系统中,开启进程必须写在__main__中, 在其他系统中不用加""" if __name__ == '__main__': p = Process(target=task) # 得到一个对象,还没有开启进程呢,知识实例化了一个进程对象 p.start() # 调用这个方法才是真正的开启进程 # 总结 1 开启进程调用的是multiprocessing 模块 中的process类, 2 在windows 中, 开启进程必须写在__main__中,别的系统不需要 3 要开启进程,就需要先得到一个进程对象, a = Process(target=aaa) 4 得到进程对象之后,进程对象名 调用start方法,开启进程 a.start()
如何开启多进程
import time from multiprocessing import Process def task(i): print(f'第{i}次') import time time.sleep(1) if __name__ == '__main__': start_time = time.time() ll = [] for i in range(5): p = Process(target=task, args=(i,)) # 通知操作系统开启进程,开启的时间有快有慢,所以顺序可能不一样 p.start() ll.append(p) # 把每个进程对象都加入ll,然后统一给他们加入join for j in ll: j.join() # join 子线程运行完之后,再运行主线程 print(123) print(time.time() - start_time) """ 1 开启多进程,如果想要将子进程运行完毕后再运行主进程,就将所有子进程加入到列表,然后统一给他们添加join方法。 2 如果不想让主进程等待子进程,就不用加join方法 """
Process类的参数
from multiprocessing import Process import time def task(name, age, gender): print(name) print(age) print(gender) if __name__ == "__main__": """ name参数 ,调用方法,p.name 修改进程名字,不传就是默认进程名字 *args 参数 args = () 传入的必须是元组 如果只有一个参数,那必须加逗号,不然会被认为是一个字符串 **kwargs 参数 kwargs = {} 必须用字典格式传参数 daemon : p.daemon = Ture 守护进程 作用:主进程结束,子进程也跟着结束。daemon必须写在start之前 """ # 开启的这个叫做子进程,开启进程以外的是主进程, p = Process(target=task, name='bb_1', args=('ben',), kwargs={'age': 18, 'gender': 'male'}) # p.daemon = True # 守护进程的作用,主进程结束,子进程也跟着结束 p.start() # time.sleep(1) # 如果这里加了等待,根据cpu的切换工作机制,会先去执行子进程再回来执行主进程,没加入等待,直到主进程执行完才执行子进程 # for i in range(10000): # print(' ') print(123) print(p.name) # Process-1 默认进程名字 """ 先执行了主进程里面的程序,如果在主进程中加入个等待1秒, 按照cpu的轮换执行机制,会先去执行子程序,然后再回来执行主程序 """ """ 总结: 子进程传参数必须用关键字传参数 ,位置参数args必须传元组 ,kwargs 必须传字典格式 传递位置参数 args 必须是元组的形式,有几个参数,函数里的参数就写几个参数,(如果元组内只有一个参数,那就加个 , 逗号) 传递关键字参数 kwargs 就写k值再函数的参数中 daemon = True 守护进程 ,p.daemon=True 必须写在start的前面, 主进程结束,子进程也必须结束 daemon必须写在start上面 p.start() 这里才是开启了进程 """
方法介绍
from multiprocessing import Process import time def task(): print('123') time.sleep(5) if __name__ == '__main__': p = Process(target=task()) p.start() # ··············· # p.terminate() # 杀死进程 # ··············· # time.sleep(1) # print(p.is_alive()) # False 看一个进程是否存活 如果前面不加sleep,会返回true 因为没来的及杀死 # ··············· p.join() # 等子进程运行完后,再运行另外线程 print('456') # 主进程和子进程之间的关系是相互独立的 """ ● p.start():启动进程,并调用该子进程中的p.run() ● p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法 ● p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁 ● p.is_alive():如果p仍然运行,返回True ● p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程 """
进程锁
# 锁:遇到的所有关于加锁的都是为了保证数据的安全 MySQL中:行锁、表锁、悲观锁、乐观锁、等 进程锁、互斥锁、GIL锁、死锁等 # 加锁的目的是为了让数据更安全 def task(i, lock): # 上一把锁 lock.acquire() print('第%s个进程进来了' % i) print('第%s个进程走了' % i) lock.release() # 释放锁 from multiprocessing import Lock from multiprocessing import Process if __name__ == '__main__': lock = Lock() # 得到一个锁对象。 for i in range(5): p = Process(target=task, args=(i, lock)) p.start() """ 用法:在主进程中得到一个锁对象,然后传给子进程,在子进程中通过锁定和释放来确保数据的安全性 from multiprocessing import lock lock = lock() lock = acquire()上锁 lock = release()释放锁 总结: 进程锁 是一种用于控制并发访问共享资源的机制,它主要的目的是防止多个进程同时修改和访问共享资源导致的数据不一致或者竞态条件 进程锁通过提供互斥访问的机制来解决这些问题,当一个进程获得了进程锁后,其他进程必须等待该进程释放锁才能继续访问共享资源 这样可以确保在任意时刻只有一个进程可以访问共享资源,从而避免了访问并发导致的问题 进程锁的意义在于保护共享资源的完整性和一致性。它确保了多个进程在并发访问共享资源时的顺序和互斥性, 避免了竞态条件和数据不一致的情况发生。进程锁是实现多进程并发安全的重要工具之一。 """
如何开启线程
方式一: def task(): print('我是线程') from multiprocessing import Process from threading import Thread if __name__ == '__main__': t = Thread(target=task) t.start() # 启动线程 print('主线程') 方式二: from threading import Thread import time class Sayhi(Thread): def __init__(self,name): super().__init__() self.name=name def run(self): time.sleep(2) print('%s say hello' % self.name) if __name__ == '__main__': t = Sayhi('ly') t.start() t.daemon = True # 线程守护,主线程结束后,子线程也结束。 # t.setDaemon(True) # 守护线程:主线程结束,子线程跟着结束 print('主线程') #####几个方法 # print(t.isAlive()) 看线程是否存在 # print(t.is_alive()) 看线程是否存在 # print(t.getName()) 获取线程名字 # print(t.name) 获取线程名字 # t.setName('ly_2') 设置线程名字 # print(t.getName()) 获取线程名字 print(threading.currentThread().getName()) #: 返回当前的线程变量。 print(threading.enumerate()[0].getName()) #: 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 print(threading.activeCount()) #: 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
如何开启多线程
from threading import Thread def task(i): print(f'子线程{i}') if __name__ == '__main__': ll = [] for i in range(5): t = Thread(target=task, args=(i,)) t.start() ll.append(t) for j in ll: j.join() print('主进程')
线程与进程的区别
1 线程共享创建它的进程的地址空间; 进程具有自己的地址空间。
2 线程可以直接访问其进程的数据段; 进程具有其父进程数据段的副本。
3 线程可以直接与其进程中的其他线程通信; 进程必须使用进程间通信与同级进程进行通信。
4 新线程很容易创建; 新进程需要复制父进程。
5 线程可以对同一进程的线程行使相当大的控制权。 进程只能控制子进程。
6 对主线程的更改(取消,优先级更改等)可能会影响该进程其他线程的行为; 对父进程的更改不会影响子进程。
····································································
1. 进程的开销远远大于线程的开销
2. 进程之间的数据是隔离的,线程之间的数据呢? 线程之间的数据是共享的,严格的来说:同一个进程下的线程之间的数据是共享的
3. 想让不同进程之间的线程之间的数据共享------->还是让进程之间通信------->线程之间也通信了--->队列
标签:__,name,start,python,print,线程,进程,多线程 From: https://www.cnblogs.com/xiaoyou898/p/17533359.html