进程是资源的一个集合,

1、一个应用程序,可以有多进程和多线程

2、默认一个程序是单进程单线程

IO操作使用多线程提高并发

计算操作使用多进程提高并发

进程与线程区别

1、线程共享内存空间,进程的内存是独立的

2、线程共享进程内存的数据,进程之间的数据是无法进行访问的

3、在同一个进程内,线程之间可以直接进行数据的访问,两个进程如果通信,必须通过一个中间代理进行通信

4、创建线程非常容易,创建新进程需要对其父进程进行一次克隆

5、一个线程可以控制和操作同一进程里的其它线程,但是进程只能操作子进程

什么时候适合多线程:

IO密集型,socket,爬虫,web

什么时候适合多进程:

CPU运算密集型,金融分析

一个简单的创建多线程例子:

import threading
import time def run(n):
print('task', n)
time.sleep(2) # 多线程
t1 = threading.Thread(target=run, args=("t1",)) # 要创建一个线程,并让线程执行run方法
t2 = threading.Thread(target=run, args=("t2",))
t1.start() # 并不代表当前线程会被立即执行,需要等待cpu进行调度
t2.start() # 启动另一个线程 print(t1.getName()) # 获取线程名
print(t2.getName()) # 非多线程
# run('t1')
# run('t2')

利用for循环创建多线程:

import threading
import time def run(n):
print('task', n)
time.sleep(2) for i in range(50):
t = threading.Thread(target=run, args=("t-%s" % i,))
t.start()

那主线程是否等子线程呢?举个例子

通过这个例子可以看出,当主线程执行完毕后,等待子线程

import time
import threading def run(num):
time.sleep(5)
print(num) t1 = threading.Thread(target=run,args=(1,))
t1.start()
print('end')

setDaemon方法:主线程执行完毕后,不等子线程,所以在这里你永远看不见子线程有结果

import time
import threading def run(num):
time.sleep(5)
print(num) for i in range(10):
t1 = threading.Thread(target=run, args=(i,))
t1.setDaemon(True) # 设置成守护线程,true ,表示主线程不等子线程
t1.start()
print('end')

join方法:等待子线程执行完毕后,再继续

import time
import threading def run(num):
time.sleep(2)
print(num) for i in range(5):
t1 = threading.Thread(target=run, args=(i,))
t1.start()
t1.join() # 主线程执行到这里就等待,直到子线程执行完毕后,再继续
print('end')

上边的例子貌似解决了,等待子线程都执行完毕后,主线程继续执行,但是变为串行了,怎么解决呢?

看下面的例子

import time
import threading def run(num):
time.sleep(2)
print(num) t_list = []
for i in range(5):
t1 = threading.Thread(target=run, args=(i,))
t1.start()
t_list.append(t1) for t in t_list:
t.join() print('main thread')

join()+参数:表示主线程在此最多等N秒

import time
import threading def run(num):
time.sleep(2)
print(num) for i in range(5):
t1 = threading.Thread(target=run, args=(i,))
# t1.setDaemon(True) # true ,表示主线程不等子线程
t1.start()
t1.join(2) # 主线程执行到这里就等待,直到子线程执行完毕后,再继续
print('end')
import threading

class MyThread(threading.Thread):
def __init__(self, func, args):
self.func = func
self.args = args
super(MyThread, self).__init__() def run(self):
self.func(self.args) def f2(arg):
print(arg) obj = MyThread(f2, 1234)
obj.start()
import threading

class MyThread(threading.Thread):
def __init__(self, n):
self.n = n
super(MyThread, self).__init__() def run(self): # 必须是run名字,定义每个线程要运行的函数
print("running task", self.n) t1 = MyThread('t1')
t2 = MyThread('t2') t1.start()
t2.start()

queue模块

import queue

q = queue.Queue(maxsize=2)  # 默认先进先出,可以添加参数maxsize=2
q1 = queue.LifoQueue() # last in fisrt out 先进后出
q2 = queue.PriorityQueue # 优先级 # put 放数据
# get 取数据
# 队列最大长度 q.put(1)
q.put(2)
q.put(3, block=False) # 当队列默认最大2条消息时候,再放就等待,可以在put里面增加block=False,timeout参数,就不等待了
task_done()和join方法
import queue

q = queue.Queue(5)

q.put(1)
q.put(2) q.get()
q.task_done() # 告诉队列这个数据我取出来
q.get()
q.task_done()
q.join() # 如果队列里面还有数据,我就等待,否则就终止,这个参数需要task_done配合一起是用

优先级队列

q = queue.PriorityQueue()

q.put([3, 'abc'])
q.put([0, 'ccc'])
print(q.get())

多线程锁机制

防止多个线程同时修改同一个共享数据

例子1:模拟多个线程修改同一个共享数据

import time
import threading NUM = 10 def func():
global NUM
NUM -= 1
time.sleep(2)
print(NUM) t_list = []
for i in range(10):
t = threading.Thread(target=func)
t.start()
t_list.append(t) for t in t_list:
t.join() print('end')

通过锁机制,同一时间只允许一个线程进行值的修改

import time
import threading NUM = 10 def func(l):
global NUM
# 加锁
l.acquire()
NUM -= 1
time.sleep(2)
print(NUM)
# 释放锁
l.release() lock = threading.Lock() for i in range(10):
t = threading.Thread(target=func, args=(lock,))
t.start()

Semaphore(信号量)

锁允许一个线程在同一时间更改数据,而Semaphore是同时允许一定数量的线程更改数据。

import time
import threading NUM = 10 def func(s):
global NUM
# 加锁
s.acquire()
NUM -= 1
time.sleep(2)
print(NUM)
# 释放锁
s.release() lock = threading.Lock()
semaphore = threading.BoundedSemaphore(3) for i in range(10):
t = threading.Thread(target=func, args=(semaphore,))
t.start()

事件(event)

python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。

event = threading.Event()

event.wait()

event.set()

event.clear()

import threading
import time event = threading.Event() def ligher():
count = 0
while True:
if count < 30:
if not event.is_set():
event.set()
print('green')
elif count < 35:
print('yellow')
elif count < 60:
if event.is_set():
event.clear()
print('red')
else:
count = 0
count += 1
time.sleep(0.3) def car(n):
count = 0
while True:
event.wait()
print("car [%s] is running.." % n)
count += 1
time.sleep(1) red_light = threading.Thread(target=ligher)
red_light.start() c1 = threading.Thread(target=car, args=(1,))
c1.start()

条件(Condition)

Timer

from threading import Timer

def hello():
print("hello, world") t = Timer(1, hello)
t.start() # after 1 seconds, "hello, world" will be printed

生产者消费者模型

例1:

import queue
import time
import threading def consumer(name):
while True:
print("%s-->取到骨头[%s]" % (name, q.get()))
time.sleep(0.5) def producer(name):
count = 0
while q.qsize() < 5:
print("%s 生产了骨头" % name, count)
q.put(count)
count += 1
time.sleep(3) q = queue.Queue(4) p1 = threading.Thread(target=producer, args=('生产者1',))
p2 = threading.Thread(target=producer, args=('生产者2',))
c1 = threading.Thread(target=consumer, args=('消费者1',))
p1.start()
p2.start()
c1.start()

例2:

import queue
import time
import threading def consumer(name):
while True:
print("%s-->取到骨头[%s]" % (name, q.get()))
time.sleep(0.5)
q.task_done() # 给生产者发一个回执,这个参数跟q.join联合是用 def producer(name):
count = 0
for i in range(10):
print("%s 生产了骨头" % name, count)
q.put(count)
count += 1
time.sleep(0.3)
q.join()
print('-----------所有骨头都吃完了-----') q = queue.Queue(4) p1 = threading.Thread(target=producer, args=('生产者1',))
# p2 = threading.Thread(target=producer, args=('生产者2',))
c1 = threading.Thread(target=consumer, args=('消费者1',))
p1.start()
# p2.start()
c1.start()

多进程multiprocessing

1、开销大

2、可以利用cpu的多核特性

:

进程间的通信

不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:

只是实现了数据的传递

Queue:

from multiprocessing import Process
from multiprocessing import Queue def f(q):
q.put([42, None, 'hello']) if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()

Pipes

Managers

2个进程修改同一个数据

from multiprocessing import Process, Manager

def f(d, l,n):
d[n] = n
l.append(n)
print(l) if __name__ == '__main__':
with Manager() as manager:
d = manager.dict() l = manager.list(range(5))
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l, i))
p.start()
p_list.append(p)
for res in p_list:
res.join() print(d)
print(l)

进程池

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

进程池中有两个方法:

  • apply
  • apply_async

apply:串行基本没用callback方法

from multiprocessing import Pool
import time def f(i):
print('hello world', i)
time.sleep(1) def callback(data):
print("exec done--->", data) if __name__ == '__main__': pool = Pool(5)
for num in range(10):
pool.apply(func=f, args=(num,))

apply_async:

from multiprocessing import Pool
import time
import os def f(i):
print('hello world', i)
time.sleep(1)
print('-->PID', i, os.getpid())
return i def callback(data): # 接收f()函数的返回值
print('-->callback > pid', data, os.getpid())
# print("exec done--->", data) if __name__ == '__main__': pool = Pool(5)
for num in range(100):
pool.apply_async(func=f, args=(num,), callback=callback) # 必须有下边的 pool.close()和 pool.join(),别问为啥
print('end')
pool.close()
pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

Python多线程、进程入门1的更多相关文章

  1. Python 多线程进程高级指南(二)

    本文是如何<优雅地实现Python通用多线程/进程并行模块>的后续.因为我发现,自认为懂了一点多线程开发的皮毛,写了那么个multi_helper的玩意儿,后来才发现我靠原来就是一坨屎.自 ...

  2. Python多线程&进程

    一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...

  3. Python 多线程 进程与线程相关概念 (一)

    0x00 并行和并发 并行:同时做某些事,可以互不干扰的同一时刻做几件事. 并发:也是同时做某些事,但是强调,同一时刻做了几件事. 0x01 并发的解决: 1)队列.缓冲区: 排队就是队列,先进先出. ...

  4. Python 多线程和线程池

    一,前言 进程:是程序,资源集合,进程控制块组成,是最小的资源单位 特点:就对Python而言,可以实现真正的并行效果 缺点:进程切换很容易消耗cpu资源,进程之间的通信相对线程来说比较麻烦 线程:是 ...

  5. Python socket进阶 多线程/进程

    #首先,什么场合下用进程,什么场合下用线程: . 计算密集型的用进程. . IO密集型的用进程. xSocket语法及相关 Socket Families(地址簇) socket.AF_UNIX un ...

  6. Day9 - Python 多线程、进程

    Python之路,Day9, 进程.线程.协程篇   本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线 ...

  7. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

  8. Python 多线程、进程

    本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...

  9. Python 多线程、多进程 (三)之 线程进程对比、多进程

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.多线程与多进 ...

  10. Python多线程、进程、协程

    本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...

随机推荐

  1. svn/git的diff、patch

    svn/git的diff.patch 前几天,正当我突突的写代码,企业微信嘀嘀一声响”在不,过来帮我看个bug”.本人一向助人为乐,高兴的冲了过去,然后就开始了一段长达1分钟的问题描述.很明显,此同学 ...

  2. ae学习

    Ae           提供者CoSA 1993年1月 版本1.0 代号Egg 主要加入法人功能layered compositing with mask, effect, transforms, ...

  3. Ansible-Tower快速入门-6.查看tower的仪表板【翻译】

    查看tower的仪表板 到这一步,我们已经可以在屏幕上看到tower的仪表板了,我们可以看到你目前"主机""资产清单"和"项目"的汇总信息, ...

  4. C语言中关于对目录的操作

    原文地址:C语言中关于对目录的操作 目录的操作不论是在嵌入式产品还是应用软件编程都是必不可少的,不同的开发语言可能略有不同,笔者主要是讨论在Linux平台下对目录的一系列操作: 1.获取当前目录操作: ...

  5. 常用的7个.htaccess代码组织某个国家的IP访问

    htAccess 文件(Hypertext Access file)是Apache Web服务器的一个非常强大的配置文件,对于这个文件,Apache有一堆参数可以让你配置出几乎随心所欲的功能. 使用. ...

  6. go语言的 数组、slice、map使用(转)

    golang群 点击加入 go语言的 数组.slice.map使用, 由于网上有很好的说明, 不需要再写了,请看这几篇: Go语言中的 Array, Slice和 Map 深入学习golang五篇,以 ...

  7. SDK截图(四):压缩位图实例

    这个问题研究了两天.<windows程序设计>中没有给出实例,MSDN也没有给出具体的例子.在知道,CSDN提问后,也没有得到答案.所以决定重新对DIB做一次彻底的研究,这大概会花去我一个 ...

  8. pageHelp的使用

    以前使用ibatis/mybatis,都是自己手写sql语句进行物理分页,虽然稍微有点麻烦,但是都习惯了.最近试用了下mybatis的分页插件 PageHelper,感觉还不错吧.记录下其使用方法. ...

  9. SVN-Server搭建及配置

    SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Subversion ...

  10. Linear Algebra lecture9 note

    Linear independence Spanning a space Basis and dimension 以上概念都是针对a bunch of vectors, 不是矩阵里的概念   Supp ...