python学习笔记(十) - 进程和线程

线程是最小的执行单元,而进程由至少一个线程组成。如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。

一.多进程

1. multiprocessing模块时跨平台版本的多线程模块

process类代表一个进程对象,创建子进程时,只需要传入一个执行函数和函数的参数,使用start方法启动

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

from multiprocessing import Process
import 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 'Process will start.'
    p.start()
    p.join()
    print 'Process end.'

2. poo线程池

对pool对象调用join方法会等待所有子进程执行完毕,调用join之前必须先调用close

from multiprocessing import Pool
import os, time, random

def long_time_task(name):
    print 'Run task %s (%s)...' % (name, os.getpid())
    start = time.time()
    time.sleep(random.random() * 3)
    end = time.time()
    print 'Task %s runs %0.2f seconds.' % (name, (end - start))

if __name__=='__main__':
    print 'Parent process %s.' % os.getpid()
    p = Pool()
    for i in range(5):
        p.apply_async(long_time_task, args=(i,))
    print 'Waiting for all subprocesses done...'
    p.close()
    p.join()
    print 'All subprocesses done.'

3. 进程间通信:

multiprocessing中使用Queue、Pipes等方式来交换数据。

from multiprocessing import Process, Queue
import os, time, random

# 写数据进程执行的代码:
def write(q):
    for value in ['A', 'B', 'C']:
        print 'Put %s to queue...' % value
        q.put(value)
        time.sleep(random.random())

# 读数据进程执行的代码:
def read(q):
    while True:
        value = q.get(True)
        print 'Get %s from queue.' % value

if __name__=='__main__':
    # 父进程创建Queue,并传给各个子进程:
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 启动子进程pw,写入:
    pw.start()
    # 启动子进程pr,读取:
    pr.start()
    # 等待pw结束:
    pw.join()
    # pr进程里是死循环,无法等待其结束,只能强行终止:
    pr.terminate()

二.多线程

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

import time, threading

# 新线程执行的代码:
def loop():
    print 'thread %s is running...' % threading.current_thread().name
    n = 0
    while n < 5:
        n = n + 1
        print 'thread %s >>> %s' % (threading.current_thread().name, n)
        time.sleep(1)
    print 'thread %s ended.' % threading.current_thread().name

print 'thread %s is running...' % threading.current_thread().name
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print 'thread %s ended.' % threading.current_thread().name

2. 给变量加锁,防止被其他线程篡改:

import time, threading
def change_it(n):
    # 先存后取,结果应该为0:
    global balance
    balance = balance + n
    balance = balance - n

balance = 10000 # 假定这是你的银行存款:
lock = threading.Lock()

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

t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print balance

锁的好处就是确保某段关键代码只能由一个线程从头到尾完整地执行。

坏处就是降低了效率,同时有可能出现死锁。

三.ThreadLocal

四.进程 vs 线程

五.分布式进程

时间: 2024-12-06 20:17:38

python学习笔记(十) - 进程和线程的相关文章

Python学习笔记 - day13 - 进程与线程

概述 我们都知道windows是支持多任务的操作系统. 什么叫"多任务"呢?简单地说,就是操作系统可以同时运行多个任务.打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务,至少同时有3个任务正在运行.还有很多任务悄悄地在后台同时运行着,只是桌面上没有显示而已. 现在,多核CPU已经非常普及了,但是,即使过去的单核CPU,也可以执行多任务.由于CPU执行代码都是顺序执行的,那么,单核CPU是怎么执行多任务的呢? 答案就是操作系统轮流让各个任务交替执行,任

python学习笔记十——异常处理

1.try: command except 错误类型,记录错误信息变量: command finally: command try...finally的用处是无论是否发生异常都要确保资源释放代码的执行.一般来说,如果没有发生错误,执行过try语句块之后执行finally语句块,完成整个流程.如果try语句块发生了异常,抛出了这个异常,此时就马上进入finally语句块进行资源释放处理.如下从几个细节讨论finally的特性. 1).try中的return: 当在try语句块中含有return语句

python学习笔记——守护进程

1 基本描述 守护进程:是系统中独立的后台服务进程, 特点:独立与终端并且周期性地执行某个任务,其生命周期长,一般随系统启动和终止. 缺点:进程的创建和销毁的时候需要消耗较多的计算机资源. 2 参考 Python实现守护进程 python中的daemon守护进程实现方法 python daemon守护进程实现 Python 守护进程 Python如何实现守护进程的方法示例 Python实例浅谈之五Python守护进程和脚本单例运行 原文地址:https://www.cnblogs.com/gen

python学习笔记-(十三)线程、进程、多线程&amp;多进程

为了方便大家理解下面的知识,可以先看一篇文章:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html 线程 1.什么是线程? 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 2.python GIL全局解释器锁(仅需了解) 无论你启多少个线程,你有多少个cpu, Python在执行的时

Python学习笔记十:日期和时间

日期和时间处理是经常会遇到的事情. 什么是Tick? 时间间隔是以秒为单位的浮点小数. 每个时间戳都以自从1970年1月1日午夜(历元)经过了多长时间来表示. Python附带的受欢迎的time模块下有很多函数可以转换常见日期格式.如函数time.time()用ticks计时单位返回从12:00am, January 1, 1970(epoch) 开始的记录的当前操作系统时间, 如下实例: 1 #!/usr/bin/python 2 import time; # This is required

python学习笔记(十五) - python连接mysql数据库

一. 安装mysql驱动: 由于mysql服务器以独立的进程运行,并通过网络对外服务,所以,需要支持python的mysql驱动来连接mysql服务器. 安装驱动:easy_install mysql-connector-python 二. 连接数据库: 下面演示使用python代码连接mysql: #!/usr/bin/env python # -*- coding: utf-8 -*- # utility @ Python # 导入MySQL驱动: import mysql.connecto

python学习笔记十六 django深入学习一

django 请求流程图 django 路由系统 在django中我们可以通过定义urls,让不同的url路由到不同的处理函数 from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), #精确匹配 url(r'^articles/([0-9]{4})/$', views.year_archive), #动态路由 url(r'^articles/([0-9]{4})/([0-9]{2

python学习笔记十五 web框架

python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. Python的WEB框架分为两类: 自己写socket,自己处理请求 基于wsgi(Web Server Gateway Interface WEB服务网关接口,实现socket功能),自己处理请求 如图示: 自己写的web框架 #!/usr/bin/env python #coding:utf-8 import socket def handle_req

python学习笔记十五 django基础

Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. 1.创建django程序 通过命令行 django-admin startproject mysite 创建project 一个工程可以包含多个app,app共用一个project的配置文件 cd mysite python manage.py startapp app01 创建app01 pyt