• python的threading.Thread类有一个run方法,用于定义线程的功能函数,可以在自己的线程类中覆盖该方法。而创建自己的线程实例后,通过Thread类的start方法,可以启动该线程,交给python虚拟机进行调度,当该线程获得执行的机会时,就会调用run方法执行线程。
  • 每个线程一定会有一个名字,尽管上面的例子中没有指定线程对象的name,但是python会自动为线程指定一个名字。
  • 当线程的run()方法结束时该线程完成。
  • 在一个进程内的所有线程共享全局变量,能够在不适用其他方式的前提下完成多线程之间的数据共享(这点要比多进程要好)
  • 缺点就是,线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)

和进程之间的区别:

  • 进程是系统进行资源分配和调度的一个独立单位.

  • 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

  • 在多线程开发中,全局变量是多个线程都共享的数据,而局部变量等是各自线程的,是非共享的
  • 区别

    • 一个程序至少有一个进程,一个进程至少有一个线程.

    • 线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高。

    • 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率

    • 线线程不能够独立执行,必须依存在进程中

    优缺点

    线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。

使用互斥锁实现线程同步

from threading import Thread,Lock
from time import sleep class Task1(Thread):
def run(self):
while True:
if lock1.acquire():
print("------Task 1 -----")
sleep(0.5)
lock2.release() class Task2(Thread):
def run(self):
while True:
if lock2.acquire():
print("------Task 2 -----")
sleep(0.5)
lock3.release() class Task3(Thread):
def run(self):
while True:
if lock3.acquire():
print("------Task 3 -----")
sleep(0.5)
lock1.release() #使用Lock创建出的锁默认没有“锁上”
lock1 = Lock()
#创建另外一把锁,并且“锁上”
lock2 = Lock()
lock2.acquire()
#创建另外一把锁,并且“锁上”
lock3 = Lock()
lock3.acquire() t1 = Task1()
t2 = Task2()
t3 = Task3() t1.start()
t2.start()
t3.start()

  运行结果:

------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
...省略... 重要方法:
t.setDaemon(True)#默认是False,True表示主线程执行到程序结尾不管子线程是否执行完,都结束程序
"""A boolean value indicating whether this thread is a daemon thread. This must be set before start() is called, otherwise RuntimeError is
raised. Its initial value is inherited from the creating thread; the
main thread is not a daemon thread and therefore all threads created in
the main thread default to daemon = False. The entire Python program exits when no alive non-daemon threads are
left. """
同样的进程中也有类似方法p.Daemon = True

主线程等待子线程执行:(同样适用于进程通信,进程join方法没有参数)

t.join() #等待子线程执行完然后主线程接着执行,变态用法,这样子线程的并发就没有意义

t.join(2)#与上面类似,不过最多等2秒

  

进程间数据不共享(与多线程不同点):

from multiprocessing import Pool, Process
import os, time l = [] def test(temp):
time.sleep(1)
l.append(temp) print("{}say hai".format(os.getpid()), l) if __name__ == '__main__':
for i in range(10):
p = Process(target=test, args=(i, ))
p.start()
p.join()#1秒执行一个(打印一次),注销此行,那么各个进程间不在等待,1秒后几乎同时输出

  打印

/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /Users/starhub/PycharmProjects/多线程/1.py
38000say hai [0]
38001say hai [1]
38002say hai [2]
38003say hai [3]
38004say hai [4]
38005say hai [5]
38006say hai [6]
38008say hai [7]
38010say hai [8]
38011say hai [9]

  如果是线程那么打印结果将是下面这样:

/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /Users/starhub/PycharmProjects/多线程/1.py
38322say hai [1]
38322say hai [1, 0]
38322say hai [1, 0, 2]
38322say hai [1, 0, 2, 3]
38322say hai [1, 0, 2, 3, 5]
38322say hai [1, 0, 2, 3, 5, 7]
38322say hai [1, 0, 2, 3, 5, 7, 9]
38322say hai [1, 0, 2, 3, 5, 7, 9, 4]
38322say hai [1, 0, 2, 3, 5, 7, 9, 4, 8]
38322say hai [1, 0, 2, 3, 5, 7, 9, 4, 8, 6]

  如果想进程间数据共享,那么可以使用特殊的数据结构(Array,Manager.dict,)

event

执行结果:

使用threading.local()方法

 import threading

 # 创建全局ThreadLocal对象:
local_school = threading.local() def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name)) def process_thread(name):
# 绑定ThreadLocal的student:
local_school.student = name
process_student() t1 = threading.Thread(target= process_thread, args=('dongGe',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('老王',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
执行结果: Hello, dongGe (in Thread-A)
Hello, 老王 (in Thread-B)

小结:

全局变量local_school就是一个ThreadLocal对象,每个Thread对它都可以读写student属性,但互不影响。你可以把local_school看成全局变量,但每个属性如local_school.student都是线程的局部变量,可以任意读写而互不干扰,也不用管理锁的问题,ThreadLocal内部会处理。

可以理解为全局变量local_school是一个dict,不但可以用local_school.student,还可以绑定其他变量,如local_school.teacher等等。

ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。

一个ThreadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题

队列(生产者与消费者)

进程池实现同步和异步:

 from multiprocessing import Pool
import time
import os def test():
print("---进程池中的进程---pid=%d,ppid=%d--"%(os.getpid(),os.getppid()))
for i in range(3):
print("----%d---"%i)
time.sleep(1)
return "hahah" def test2(args):
print("---callback func--pid=%d"%os.getpid())
print("---callback func--args=%s"%args) pool = Pool(3)
pool.apply(func=test)#同步进程
'''
---进程池中的进程---pid=36031,ppid=36030--
----0---
----1---
----2---
----主进程-pid=36030----
'''
pool.apply_async(func=test,callback=test2)
time.sleep(5)#结果如下如果没有延迟,那么执行结果apply(),主进程没有等待异步进程
'''
---进程池中的进程---pid=36180,ppid=36179--
----0---
----1---
----2---
---进程池中的进程---pid=36181,ppid=36179--
----0---
----1---
----2---
---callback func--pid=36179
---callback func--args=hahah
----主进程-pid=36179----
''' print("----主进程-pid=%d----"%os.getpid())

进程池异步 apply_async()方法阐明Pool(5)参数意义

 from multiprocessing import Pool, Process
# from threading import Thread
import os, time def test(temp):
time.sleep(1) print("{}say hai".format(os.getpid()), temp) if __name__ == '__main__':
p = Pool(4)
for i in range(40):
p.apply_async(func= test,args=(i, )) time.sleep(2)
print('主进程执行完毕') 打印结果:

#/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /Users/starhub/PycharmProjects/多线程/1.py
39798say hai 0
39799say hai 1
39800say hai 2
39801say hai 3
39798say hai 4
39799say hai 5#下面的6,7出现的时间有延迟,证明进程最大并发数就是Pool(5)初始化参数5
39800say hai 6
39801say hai 7
主进程执行完毕

 from multiprocessing import Pool, Process
# from threading import Thread
import os, time def test(temp):
time.sleep(1) print("{}say hai".format(os.getpid()), temp) if __name__ == '__main__':
p = Pool(4)
for i in range(40):
p.apply_async(func= test,args=(i, )) p.close()#关闭Pool,使其不再接受新的任务
p.join()#线程join必须配合close使用,等待线程池所有进程执行完毕。完全失去了异步进程的意义(主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;)
print('主进程执行完毕') 执行结果是隔一秒打印5行,即执行5个

40138say hai 1
40137say hai 0
40139say hai 2
40140say hai 3
40138say hai 4
40137say hai 5
40139say hai 6
40140say hai 7
40137say hai 8
40138say hai 9
40139say hai 10
40140say hai 11
40137say hai 12
40138say hai 13
40139say hai 14
40140say hai 15
40138say hai 16
40137say hai 17
40139say hai 18
40140say hai 19
40138say hai 20
40137say hai 21
40139say hai 22
40140say hai 23
40138say hai 24
40137say hai 25
40139say hai 26
40140say hai 27
40138say hai 28
40137say hai 29
40139say hai 30
40140say hai 31
40137say hai 32
40139say hai 34
40138say hai 33
40140say hai 35
40137say hai 36
40139say hai 37
40138say hai 38
40140say hai 39
主进程执行完毕

python 多线程,进程的理解的更多相关文章

  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. .NET程序员也学Node.js——初识Node.js

    清明在石门休了八天假,一眨眼,4月又到中旬了...看到.NET在天朝彻底沦陷而又无能为力,我开始尝试去学习一些新的东西来充实自己,我自然是打死不会去学java的,没有为什么,于是乎,最近开始学习一些前 ...

  2. ef code first

    , 网上有很多的ef  code first 的使用的方式,很乱,下面是我自己整理出来的,有什么不正确的地方还请指正,本人菜鸟一枚! 1.新建一个类库 =>引用 右击 管理NuGet程序包 添加 ...

  3. 学习Sass笔记之概念篇

    1 什么是CSS预处理器 首先我们了解一下什么是CSS预处理器:通俗的说,“CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用.CSS 预 ...

  4. 你的计算机也可以看懂世界——十分钟跑起卷积神经网络(Windows+CPU)

    众所周知,如果你想研究Deep Learning,那么比较常用的配置是Linux+GPU,不过现在很多非计算机专业的同学有时也会想采用Deep Learning方法来完成一些工作,那么Linux+GP ...

  5. [JavaWeb]SpringSecurity-OAuth2.0 统一认证、资源分离的配置,用于分布式架构、模块化开发的认证体系

    前言 关于 OAuth2.0的认证体系,翻阅了好多资料,RCF 文档太多,看了一半就看不下去了,毕竟全英文的文档看起来,是有一点让我烦躁,但也对 OAuth2.0的认证流程有了一个基本的概念,之前用 ...

  6. spring 动态创建数据源

    项目需求如下,公司对外提供服务,公司本身有个主库,另外公司会为每个新客户创建一个数据库,客户的数据库地址,用户名,密码,都保存在主数据库中.由于不断有新的客户加入,所以要求,项目根据主数据库中的信息, ...

  7. ECharts 实现人民的名义关系图谱 代码开源

    1.什么是ECharts ECharts是百度开源的纯 Javascript 图表库,目前开源可以与highcharts相匹敌的一个图表库,相信有很多国内用户使用. 官网 http://echarts ...

  8. callLater

    UIComponent的方法,该方法在每次更新屏幕之前,Flash Player 或 AIR 都会调用为更新预定的函数集.有时,应在下次更新时调用函数,以执行为当前更新预定的其余代码.部分功能(如效果 ...

  9. stl_algorithm算法之排序算法

    排序算法: 注意:容器中必须重载 op< ,排序中stl标准中要求用小于来进行比较. 7.53.sort //全排序. 7.54.stable_sort //稳定排序.两个或两个以上的相邻且相等 ...

  10. 谈谈一些有趣的CSS题目(十五)-- 奇妙的 background-clip: text

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...