1、首先是定义
进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程。进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统中的并发执行的单位。
线程:单个进程中执行中每个任务就是一个线程。线程是进程中执行运算的最小单位。
2、一个线程只能属于一个进程,但是一个进程可以拥有多个线程。多线程处理就是允许一个进程中在同一时刻执行多个任务。
3、线程是一种轻量级的进程,与进程相比,线程给操作系统带来侧创建、维护、和管理的负担要轻,意味着线程的代价或开销比较小。
4、线程没有地址空间,线程包含在进程的地址空间中。线程上下文只包含一个堆栈、一个寄存器、一个优先权,线程文本包含在他的进程 的文本片段中,进程拥有的所有资源都属于线程。所有的线程共享进程的内存和资源。 同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段, 寄存器的内容,栈段又叫运行时段,用来存放所有局部变量和临时变量。
5、父和子进程使用进程间通信机制,同一进程的线程通过读取和写入数据到进程变量来通信。
6、进程内的任何线程都被看做是同位体,且处于相同的级别。不管是哪个线程创建了哪一个线程,进程内的任何线程都可以销毁、挂起、恢复和更改其它线程的优先权。线程也要对进程施加控制,进程中任何线程都可以通过销毁主线程来销毁进程,销毁主线程将导致该进程的销毁,对主线程的修改可能影响所有的线程。
7、子进程不对任何其他子进程施加控制,进程的线程可以对同一进程的其它线程施加控制。子进程不能对父进程施加控制,进程中所有线程都可以对主线程施加控制。
进程和线程都有ID/寄存器组、状态和优先权、信息块,创建后都可更改自己的属性,都可与父进程共享资源、都不鞥直接访问其他无关进程或线程的资源。
导包方式:
from multiprocessing import Queue # 队列
from multiprocessing import Manager, Pool # 通过Manager创建队列,进程池
from multiprocessing import Process # 进程
import multiprocessing # 这种也可以
点进去看源码可得:
class Process(object):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
# 以下省略
方法介绍:
属性介绍:
import time
from multiprocessing import Process
def piao(name):
print('%s piao' %name)
time.sleep(2)
print('%s piao end' %name)
p1=Process(target=piao,args=('e',)) #必须加,号才是元组
p1.start()
队列先进先出,栈后进先出
创建队列的类(底层就是以管道和锁定的方式实现):
Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递
maxsize是队列中允许最大项数,省略则无大小限制。
q.put方法用以插入数据到队列中
put方法还有两个可选参数:blocked和timeout。
如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。
如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。
q.get方法可以从队列读取并且删除一个元素。
get方法有两个可选参数:blocked和timeout。
如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。
如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常.
q.get_nowait():同q.get(False)
q.put_nowait():同q.put(False)
q.empty():调用此方法时q为空则返回True,该结果不可靠,比如在返回True的过程中,如果队列中又加入了项目。
q.full():调用此方法时q已满则返回True,该结果不可靠,比如在返回True的过程中,如果队列中的项目被取走。
q.qsize():返回队列中目前项目的正确数量,结果也不可靠,理由同q.empty()和q.full()一样
以下是多线程实现队列的存取实例:
from queue import Queue
import threading
# 创建队列,最大存放6个
que = Queue(6)
# 这个是用来存进队列的自定义线程类
class PutThread(threading.Thread):
def __init__(self, num):
super(PutThread, self).__init__() # 一定记住要父类初始化
self.num = num # 这个是传入的参数
def run(self): # 自定义的线程,重写run方法实现
super(PutThread, self).run()
for i in range(self.num):
que.put(i)
# 这个是用来队列取出的自定义线程类
class GetThread(threading.Thread):
def __init__(self):
super(GetThread, self).__init__()
# threading.Thread.__init__(self, target==target, args=args)
def run(self): # 要自定义再写
while True:
ret = que.get()
print(ret)
if __name__ == '__main__':
get_thread = GetThread()
put_thread = PutThread(5)
put_thread.start()
put_thread.join() # 使堵塞
get_thread.start()
进程队列的实现:
import queue,time
import multiprocessing # 不同的导入方法
def foo(q):
time.sleep(1)
print("son process",id(q))
q.put(123)
q.put("yuan")
if __name__ == '__main__':
# 导包方式不同,使用不一样
q=multiprocessing.Queue()
p=multiprocessing.Process(target=foo,args=(q,))
p.start()
#p.join()
print("main process",id(q))
print(q.get())
print(q.get())