Python中的进程和线程

一、Python中两种创建进程的方式

1、os.fork只适用于Linux/Mac
2、使用multiprocessing模块可以跨平台实现多进程

使用os.fork(),像Linux平台上那样创建多进程。

# multiprocessing.py
import os

print 'Process (%s) start...' % os.getpid()
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)

关于fork需要知道以下几点:fork之后程序相当于分叉了,fork会返回两次,每次的返回值都为int。如果此值为0,表示当前进程为父进程,如果此值不为0表示当前进程为子进程且此值代表子进程的id。

使用multiprocessing
进程之间是不共享数据的,它们不共享内存,所以创建进程比较耗费资源。进程之间通信需要类似管道的机制。

from multiprocessing import Process
import time

x = 100


def f():
    while 1:
        time.sleep(2)
        print(x)#这里会一直输出100


if __name__ == '__main__':#必须在main中才可以创建进程
    x=2
    p = Process(target=f)
    p.start()
    time.sleep(7)
    x=3
    time.sleep(3)
    print("over")
    print(x)

二、编程上的一些用法

主要是两个模块:multiprocessing和threading

1、获取当前线程名称

multiprocessing.current_process().name
threading.current_thread().name

2、多线程编程时,默认情况下,主线程结束之后,等待全部子线程执行完毕才会退出

import threading
import time

def run():
    time.sleep(2)
    print('当前线程的名字是: ', threading.current_thread().name)
    time.sleep(2)


if __name__ == '__main__':

    start_time = time.time()

    print('这是主线程:', threading.current_thread().name)
    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        t.start()

    print('主线程结束!' , threading.current_thread().name)
    print('一共用时:', time.time()-start_time)

3、将子线程设置为deamon类型,则主线程不必等待子线程结束

import threading
import time

def run():

    time.sleep(2)
    print('当前线程的名字是: ', threading.current_thread().name)
    time.sleep(2)


if __name__ == '__main__':

    start_time = time.time()

    print('这是主线程:', threading.current_thread().name)
    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        t.setDaemon(True)
        t.start()

    print('主线程结束了!' , threading.current_thread().name)
    print('一共用时:', time.time()-start_time)

4、在主线程中,使用子线程.join()来等待子线程运行结束

join()会将一切权力交给子线程,主线程会阻塞直到子线程结束。

import threading
import time

def run():

    time.sleep(2)
    print('当前线程的名字是: ', threading.current_thread().name)
    time.sleep(2)


if __name__ == '__main__':

    start_time = time.time()

    print('这是主线程:', threading.current_thread().name)
    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        t.setDaemon(True)
        t.start()

    for t in thread_list:
        t.join()

    print('主线程结束了!' , threading.current_thread().name)
    print('一共用时:', time.time()-start_time)

三、进程和线程的区别和联系

  • 进程是重量级的,需要占用较多资源。线程是轻量级的。
  • 一个进程可以包括多个线程,但是一个进程只有一个主线程。操作系统的全部进程组成一棵树,父进程的死亡会导致子进程的终止。
  • 同一进程的多个线程之间是共享数据的,不同进程之间数据相互独立(进程之间交流比较困难)。
  • 尽量使用线程。

Chrome里面每一个tab页都是一个独立的进程,可以打开任务管理器查看一下。
Tomcat中每一次请求都会开辟一个线程,Java强大的异常机制把错误牢牢地抓住了,不然一个线程一崩整个网站就崩了(因为整个tomcat程序就是一个进程,进程中的子线程崩了其它子线程也要受牵连,整个进程就崩了)。

四、为什么说Python中的线程有点鸡肋

不同线程同时访问资源时,需要使用保护机制,Python中使用GIL(解释器全局锁)。直观上,这是一个加在解释器上的全局(从解释器的角度看)锁。这意味着对于任何Python程序,不管有多少的处理器,任何时候都总是只有一个线程在执行。所以,如果没有IO操作,python中的多线程比单线程效率还低。

在任意时间只有一个Python解释器在解释Python bytecode。
如果你的代码是CPU密集型,多个线程的代码很有可能是线性执行的。所以这种情况下多线程是鸡肋,效率可能还不如单线程因为线程切换白费事。
但是,如果你的代码是IO密集型,多线程可以明显提高效率。例如制作爬虫,绝大多数时间爬虫是在等待socket返回数据。这个时候C代码里是有release GIL的,最终结果是某个线程等待IO的时候其他线程可以继续执行。

参考资料

关于Python多线程、多进程,看完廖雪峰的教程就足够了。
廖雪峰Python教程

转载于:https://www.cnblogs.com/weiyinfu/p/7845570.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值