1.进程创建方式

import time
import os
from multiprocessing import Process
def func ():
    time.sleep(1)
    print(1,os.getpid(),os.getppid())

if __name__ == '__main__':
    #异步执行func,在一秒钟的时间通过生成多个子进程来执行多个func
    #1.先实例化
    #2.实例化对象.start()
    # 目标函数:target=
    Process(target=func).start()   #process类通知操作系统要为当前代码快在开辟一个进程,是异步过程

使用Process模块

import time
from multiprocessing import Process
class Myprocess(Process): #继承Process类
    def __init__(self,name):  #重新父类的__init__方法
        super().__init__()
        self.name =name

    def run(self):  #必须是run函数名
        print(os.getpid(),os.getppid(),'我爱你%s' % self.name)
        time.sleep(3)
if __name__ == '__main__':
    start_time = time.time()
    p1 = Myprocess('kobe')
    p2 = Myprocess('kobe')
    p3 = Myprocess('kobe')
    p1.start()
    p2.start()
    p3.start()
    p1.join()  #阻塞,直到p1对应的进程结束之后,才结束阻塞,是异步阻塞,阻塞等待一个子进程结束
    p2.join()
    p3.join()
    print(time.time()-start_time)
    ##阻塞一个子进程:p.join()
    #阻塞多个子进程,将子进程加入到列表,然后分别阻塞
'''
10600 9384 我爱你kobe
10448 9384 我爱你kobe
10032 9384 我爱你kobe
1.1659998893737793
从上面结果来看,我们知道join也是异步阻塞的,在同一秒钟分别执行了p1,p2,p3的time.sleep()
和我本来预想的要阻塞3s+是结果是不同的
'''

继承Process类创建多进程

2.线程创建方式

from threading import Thread
import os
def func():
    print('in fucn ',os.getpid())
print('in main ',os.getpid())
Thread(target=func).start()
#两个打印pid是一样的,说明线程是由进程产生的

使用Thread模块

from threading import Thread
import time
class Sayhi(Thread):
    def __init__(self,name):
        super().__init__()   #重写父类的__init__方法
        self.name=name
    def run(self):
        time.sleep(2)
        print('%s say hello' % self.name)

if __name__ == '__main__':
    t = Sayhi('kobe')
    t.start()
    print('主线程')

继承Thread类创建多线程

3.进程和线程的区别

线程和进程的区别
   进程: 数据隔离(但是也可以丛进程间的数据共享)  开销大
   线程: 数据共享 开销小
   cpython中多进程可以使用多核(并发编程),多线程不可以使用多核  通俗来讲:比如有个4核(cpu)的主机,当使用多进程的时候,系统会自动的根据进程调度算法来分配今晨给资源,然后分别在不同的cpu上面执行,这就是多进程                    当时用多线程的时候,由于GIL锁的存在,多线程始终是在一个cpu上面执行,造成闲的cpu闲死,忙的cpu忙死

os.getpid()不同

#线程
from threading import Thread
import os
import time
def func():
    print('in func',os.getpid())
tt = Thread(target=func)
tt.start()
print('in main', os.getpid())#进程
from multiprocessing import Process
import os
import time
def func():
    print('in func',os.getpid())
if __name__ == '__main__':
    tt = Process(target=func)
    tt.start()
    print('in main', os.getpid())

注意线程不需要if __name__ == '__main__':  进程和线程的创建原理不同,所以不需要if __name__ == '__main__',但是可以使用这种方式  因为新的线程是在主线程的内存中,所以新的线程和主线程共享同一段代码,不需要import导入,也就不存在子线程中又重复一次创建线程的过程

二者pid对比:  在进程内,父进程创建的所有子进程都是不同的pid,说明父进程只是创建了子进程并在子进程执行代码的时候会import 父进程文件,其余父子相互之间独立,使用不同的内存空间,所以pid不同  在线程中,主线程和子线程的pid完全相同,说明子线程是在主线程内部创建出来的,并且主线程会所有子线程的结束才结束。

 二者开销对比

#线程开销时间
import time
from threading import Thread
def func(item):
  item +=1
if __name__ == '__main__':
    start = time.time()
    t_l = []
    for i in range(100):
        t = Thread(target=func,args=(i,))
        t.start()
        t_l.append(t)
    for t in t_l:
        t.join()
    print(time.time()-start)

#进程开销时间
import time
def func(item):
  item +=1
from multiprocessing import Process
if __name__ == '__main__':
    start = time.time()
    t_l = []
    for i in range(100):
        t = Process(target=func,args=(i,))
        t.start()
        t_l.append(t)
    for t in t_l:
        t.join()
    print(time.time()-start)

注意:为什么要join()?  因为要等待所有线程或进程全部都运行完,才计算时间  不能再func()函数里面写join()方法,这样就是同一时间只有一个线程或进程在之心,变成同步的了

二者开销对比:  分别执行上面代码,能够看到,做相同的操作,100个进程使用的时间比100个线程使用时间更长  说明进程在创建\销毁\上下文切换之间,需要更多的时间和系统资源

 二者数据是否共享

#多个线程之间共享全局变量
from threading import Thread
item = 0
def func():
    global item
    item +=1
f_l= []
for ii in range(1000):
    tt = Thread(target=func)
    tt.start()
    f_l.append(tt)

[x.join() for x in f_l ]
print(item)

#多个进程之间数据不共享(但是可以通过Manager来实现共享)
from multiprocessing import Process,Manager
item = 0
def func():
    global item
    item +=1
if __name__ == '__main__':
    f_l= []
    for ii in range(10):
        tt = Process(target=func)
        tt.start()
        f_l.append(tt)
    [x.join() for x in f_l ]
    print(item)

二者数据是否共享:  在线程内,主线程内的全局变量对于子线程来说完全共享,其他不是全局的就不共享  在进程内,父进程和子线程的数据完全隔离,因为父子之间分别有不同的内存空间。

tets

python进阶之 进程&线程区别的更多相关文章

  1. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  2. python学习笔记-进程线程

    1.什么是进程(process)? 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述 ...

  3. Python异常处理和进程线程-day09

    写在前面 上课第九天,打卡: 最坏的结果,不过是大器晚成: 一.异常处理 - 1.语法错误导致的异常 - 这种错误,根本过不了python解释器的语法检测,必须在程序运行前就修正: - 2.逻辑上的异 ...

  4. python基础(16)-进程&线程&协程

    进程之multiprocessing模块 Process(进程) Process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建. 介绍 初始化参数 Process([group [, t ...

  5. python网络编程--进程线程

    一:什么是进程 一个程序执行时的实例被称为一个进程. 每个进程都提供执行程序所需的资源.一个进程有一个虚拟地址空间.可执行代码.对系统对象的开放句柄.一个安全上下文.一个独特的进程标识符.环境变量.一 ...

  6. python进阶之 进程编程

    1.进程 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所有内 ...

  7. Python并发编程-进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  8. 【Python】【进程&线程】

    #[[进程 和 线程 ]] """ # [多进程]'''import os print ('Process (%s) start...' % os.getpid()) # ...

  9. python系列7进程线程和协程

    目录 进程 线程 协程  上下文切换 前言:线程和进程的关系图 由下图可知,在每个应用程序执行的过程中,都会去产生一个主进程和主线程来完成工作,当我们需要并发的执行的时候,就会通过主进程去生成一系列的 ...

随机推荐

  1. Protobuf3 序列化

    在message_lite.h中定义了SerializeToString ,SerializeToArray ,SerializeToCodedStream ,SerializeToZeroCopyS ...

  2. 重读redis设计与实现

    重读了一遍redis设计与实现,这次收获也不错,把之前还有些疑惑的点:redis跳跃表的原理.redis持久化的方法.redis复制.redis sentinel.redis集群等,都重新熟悉了一遍, ...

  3. Replication基础(六) 复制中的三个线程(IO/SQL/Dump)

    Reference:  https://blog.csdn.net/sun_ashe/article/details/82181811?utm_source=blogxgwz1 简介在MySQL复制技 ...

  4. Java多线程系列——从菜鸟到入门

    持续更新系列. 参考自Java多线程系列目录(共43篇).<Java并发编程实战>.<实战Java高并发程序设计>.<Java并发编程的艺术>. 基础 Java多线 ...

  5. go语言字符串的连接和截取

    字符串的连接: https://studygolang.com/articles/12281?fr=sidebar 字符串的截取: https://studygolang.com/articles/9 ...

  6. Laravel 执行流程(一)之自动加载

    定位 从 public/index.php 定位到 bootstrap/autoload.php 从 bootstrap/autoload.php 定位到 vendor/autoload.php 从 ...

  7. 服务器tail输出正常,vim打开中文乱码

    修改服务器端, 在/etc/vim/vimrc文件末尾加上 set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936set termencodi ...

  8. linux windows安装python的最佳方式,miniconda

    1.在linux安装python文章很多,但是步骤很多,没搞好还会把yum命令弄坏,要修复.这件事就发生在我身上,准确说不是我造成的,是总监自己安装python造成yum损坏的,然后需要运维去百度修改 ...

  9. 一个自定义python分布式专用爬虫框架。支持断点爬取和确保消息100%不丢失,哪怕是在爬取进行中随意关停和随意对电脑断电。

    0.此框架只能用于爬虫,由框架来调度url请求,必须按照此方式开发,没有做到类似celery的通用分布式功能,也不方便测试.可以使用另外一个,基于函数式编程的,调度一切函数的分布式框架,做到了兼容任何 ...

  10. linux查找并替换命令

     find ./ -maxdepth 3 -type f -name "*Makefile"  |xargs sed -i "s/CXX = g++/CXX = ccac ...