进程是资源的一个集合,

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. BZOJ 3675 序列分割

    斜率优化.注意要判分母为0的情况.dp数组可以滚一维. #include<iostream> #include<cstdio> #include<cstring> ...

  2. 【转】slice,substr和substring的区别

    首先,他们都接收两个参数,slice和substring接收的是起始位置和结束位置(不包括结束位置),而substr接收的则是起始位置和所要返回的字符串长度.直接看下面例子: var test = ' ...

  3. 【转】Unity3d + NGUI 的多分辨率适配

    原文地址:http://www.cnblogs.com/cqgreen/p/3348154.html   一.当下移动设备的主流分辨率(数据来自“腾讯分析移动设备屏幕分辨率分析报告”) 1.1 iOS ...

  4. New Training Table

          2014_8_15 CodeForces 261 DIV2 A. Pashmak and Garden 简单题   B. Pashmak and Flowers    简单题   C. P ...

  5. Discuz 7.0版块横排显示版块图标和版块简介的方法

    Discuz 7.0版块横排显示版块图标和版块简介的方法 最近很多朋友咨询Discuz论坛设置论坛版块横排后,如何设置显示版块图标和简介的问题. 一.显示板块图标 找到templates\defaul ...

  6. WWDC 2014 发布会 Keynote 视频下载 3.6G 1080P地址

    我费尽九牛二虎之力,终于可以下载这个1080P高清的视频了,话说今天凌晨我是看的图文直播,现在终于有视频了,大家会不会很激动啊,好废话不多说,我把下载地址发给大家! 百度云:http://pan.ba ...

  7. tinyhttpd源码分析

    我们经常使用网页,作为开发人员我们也部署过httpd服务器,比如开源的apache,也开发过httpd后台服务,比如fastcgi程序,不过对于httpd服务器内部的运行机制,却不是非常了解,前几天看 ...

  8. OpenGL阴影,Shadow Mapping(附源程序)

    实验平台:Win7,VS2010 先上结果截图(文章最后下载程序,解压后直接运行BIN文件夹下的EXE程序): 本文描述图形学的两个最常用的阴影技术之一,Shadow Mapping方法(另一种是Sh ...

  9. 关于对CSS尺寸单位'em'的长期误解

    一直以来认为'em'是相对于父元素的字体大小. 直到今天学习移动WEB开发,重新复习css的尺寸大小时,惊奇发现:对em深深的误解了!!! 在CSS官网对em的解释实例是: a. h1{line-he ...

  10. JS this指向问题

    <button onclick=(function(){alert(this)})()>I'm button</button>//this指代window <button ...