热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python对象锁_Python学习之进程和线程

Python学习之进程和线程Python学习目录在Mac下使用Python3Python学习之数据类型Python学习之函数Python学习之高级特性Python学习之函数式编程P
Python学习之进程和线程

Python学习目录

  1. 在Mac下使用Python3
  2. Python学习之数据类型
  3. Python学习之函数
  4. Python学习之高级特性
  5. Python学习之函数式编程
  6. Python学习之模块
  7. Python学习之面向对象编程
  8. Python学习之面向对象高级编程
  9. Python学习之错误调试和测试
  10. Python学习之IO编程
  11. Python学习之进程和线程
  12. Python学习之正则
  13. Python学习之常用模块
  14. Python学习之网络编程

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

有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。

a93d74e94f1b9831feed0b684ea3949e.png
进程

Python的os模块封装了常见的系统调用,其中包括fork,可以在Python程序中轻松创建子进程:

import osprint('Process (%s) start...' % os.getpid())# Only works on Unix/Linux/Mac:pid = os.fork()if pid == 0: print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))else: print('I (%s) just created a child process (%s).' % (os.getpid(), pid))

运行结果如下:

Process (876) start...I (876) just created a child process (877).I am child process (877) and my parent is 876.

由于Windows没有fork调用,上面的代码在Windows上无法运行。由于Mac系统是基于BSD(Unix的一种)内核,所以,在Mac下运行是没有问题的,推荐大家用Mac学Python!

multiprocessing

如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择。由于Windows没有fork调用,难道在Windows上无法用Python编写多进程的程序?

由于Python是跨平台的,自然也应该提供一个跨平台的多进程支持。multiprocessing模块就是跨平台版本的多进程模块。

multiprocessing模块提供了一个Process类来代表一个进程对象,下面的例子演示了启动一个子进程并等待其结束:

from multiprocessing import Processimport os# 子进程要执行的代码def run_proc(name): print('Run child process %s (%s)...' % (name, os.getpid()))if __name__=='__main__': print('Parent process %s.' % os.getpid()) p = Process(target=run_proc, args=('test',)) print('Child process will start.') p.start() p.join() print('Child process end.')

执行结果如下:

Parent process 928.Process will start.Run child process test (929)...Process end.

创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,这样创建进程比fork()还要简单。

join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。

线程

Python的标准库提供了两个模块:_thread和threading,_thread是低级模块,threading是高级模块,对_thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。

启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行:

import time, threading# 新线程执行的代码:def loop(): print(&#39;thread %s is running...&#39; % threading.current_thread().name) n &#61; 0 while n <5: n &#61; n &#43; 1 print(&#39;thread %s >>> %s&#39; % (threading.current_thread().name, n)) time.sleep(1) print(&#39;thread %s ended.&#39; % threading.current_thread().name)print(&#39;thread %s is running...&#39; % threading.current_thread().name)t &#61; threading.Thread(target&#61;loop, name&#61;&#39;LoopThread&#39;)t.start()t.join()print(&#39;thread %s ended.&#39; % threading.current_thread().name)

执行结果如下&#xff1a;

thread MainThread is running...thread LoopThread is running...thread LoopThread >>> 1thread LoopThread >>> 2thread LoopThread >>> 3thread LoopThread >>> 4thread LoopThread >>> 5thread LoopThread ended.thread MainThread ended.Lock

多线程和多进程最大的不同在于&#xff0c;多进程中&#xff0c;同一个变量&#xff0c;各自有一份拷贝存在于每个进程中&#xff0c;互不影响&#xff0c;而多线程中&#xff0c;所有变量都由所有线程共享&#xff0c;所以&#xff0c;任何一个变量都可以被任何一个线程修改&#xff0c;因此&#xff0c;线程之间共享数据最大的危险在于多个线程同时改一个变量&#xff0c;把内容给改乱了。

balance &#61; 0lock &#61; threading.Lock()def run_thread(n): for i in range(100000): # 先要获取锁: lock.acquire() try: # 放心地改吧: change_it(n) finally: # 改完了一定要释放锁: lock.release()

当多个线程同时执行lock.acquire()时&#xff0c;只有一个线程能成功地获取锁&#xff0c;然后继续执行代码&#xff0c;其他线程就继续等待直到获得锁为止。

获得锁的线程用完后一定要释放锁&#xff0c;否则那些苦苦等待锁的线程将永远等待下去&#xff0c;成为死线程。所以我们用try...finally来确保锁一定会被释放。

ThreadLocal

import threading# 创建全局ThreadLocal对象:local_school &#61; threading.local()def process_student(): # 获取当前线程关联的student: std &#61; local_school.student print(&#39;Hello, %s (in %s)&#39; % (std, threading.current_thread().name))def process_thread(name): # 绑定ThreadLocal的student: local_school.student &#61; name process_student()t1 &#61; threading.Thread(target&#61; process_thread, args&#61;(&#39;Alice&#39;,), name&#61;&#39;Thread-A&#39;)t2 &#61; threading.Thread(target&#61; process_thread, args&#61;(&#39;Bob&#39;,), name&#61;&#39;Thread-B&#39;)t1.start()t2.start()t1.join()t2.join()

执行结果&#xff1a;

Hello, Alice (in Thread-A)Hello, Bob (in Thread-B)

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

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

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

下一篇&#xff1a;Python学习之正则参考文献&#xff1a;K码农-http://kmanong.top/kmn/qxw/form/home?top_cate&#61;28



推荐阅读
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Python多进程遇到的问题
    多进程共享对象我有一个IpConnectionPool对象需要多个进程共享创建BaseManager注册Ip ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 线程漫谈——线程基础
    本系列意在记录Windwos线程的相关知识点,包括线程基础、线程调度、线程同步、TLS、线程池等。进程与线程理解线程是至关重要的,每个进程至少有一个线程,进程是线程的容器,线程才是真正的执行体,线程必 ... [详细]
  • 1.背景java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题。在Java语言中,增量操作符(++)不是原子的, ... [详细]
  • GPS 校验和 代码_Linux recovery 移除签名校验
    原创作者:王锐,多年Linux系统、龙芯平台移植与优化研发经验,LinuxContributor、Mozillian。背景某个设备配套的刷 ... [详细]
  • 接口自动化相关面试题
    你好,我是懂Java的测试最近辅导简历,有同学向我反馈,自学过接口自动化、没有落地接口自动化项目办?还有很多同学落地实践过自 ... [详细]
  • JAVA动态代理(JDK版本)
    java,动态 ... [详细]
  • JavaBean和Map 转换 用反射方法实现
    由于JavaBean(实体类)结构与Map类似,我们可以把JavaBean与Map进行转换 ... [详细]
  • SimpleDateFormat类所在java包位置:java.text.SimpleDateFormat。继承结构如下:复制代码java.lang. ... [详细]
  • 开发笔记:Java多线程深度探索
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java多线程深度探索相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 操作系统基础知识(常用面试题)
    1.进程和线程有什么区别?进程(Process)是系统进行资源分配和调度的基本单位,线程(Thread)是CPU调度和分配 ... [详细]
  • 内容多有疏漏,有问题欢迎提出目录java内存模型的概念原子性(Atomicity)可见性(Visibility࿰ ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
author-avatar
小白一枚
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有