关于Python和Java的多进程多线程计算方法对比

原文请见

关于Python和Java的多进程多线程计算方法对比

搞大数据必须要正视的一个问题就是并行计算。就像执行一件任务一样,大伙一起同时干,才有效率,才会很快出成果。正所谓“众人拾柴火焰高”~

对于并行计算,有很多高大上的概念,我也不全懂。这里就单单罗列一下我对于多进程和多线程计算的理解和总结。

在计算机中,处理一个任务,可以在一个进程中,也可以在一个线程中,确切的说,执行的话都得靠一个个线程来。在我们做某件事的时候,往往需要同时干多个任务才能达到我们所要的效果,比如说看电影,就要让计算机实现让人“看”的任务,又要实现让人“听”的任务。计算机根据具体CPU的情况,开多个进程,而每个进程,又可以有多个线程。

先说“多进程”:

在Python中,实现多进程是比较容易的。我们可以使用multiprocessing进行进程的创建,比如说

import multiprocessing as mp
p = mp.Process(target=run_proc, args=('fireling',), name='Run_procProcess')
p.start()
p.join()

这样就创建了一个进程,用p表示,其中run_proc表示你用子进程运行的函数。

如果觉得这样不过瘾,还可以采用进程池创建多个进程,涉及到了两种用法:pool-apply用法和pool-map用法,本质上跟创建单个进程是一样的。

还是要用到multiprocessing包,先创建一个进程池

p = mp.Pool()
p.map(run_proc, [i for i in range(m)])
p.close()
p.join()

在Java中,程序都是在JVM上运行的,一个JVM占一个进程,所以多进程的概念,应该不存在。

再说“多线程”:

和多进程的思路类似,我们也可以实现对线程的创建,在Python中,使用threading包实现。比如说

import threading
t = threading.Thread(target=run_thread, args=('fireling', ), name='Run_threadThread')
t.start()
t.join()

这样就创建了一个线程,用t表示,其中run_thread表示你用子线程运行的函数。

但是由于多线程处理任务,往往有些变量由所有线程共享,这种变量叫全局变量,在所有线程中,这种变量只保存一份。所以多线程处理任务,特别是对于全局变量修改的时候,我们往往要加线程锁,保证在对某个全局变量修改的时候,只有一个线程接触到它。

首先要先声明线程锁,

lock = threading.Lock()

在这些线程调用的函数定义中,我们可以加两句话:

lock.acquire() # 获取线程锁
xxxxxxxxxxx 此处省略若干代码
lock.release() # 释放线程锁

全局锁针对的是所有线程的全局变量,那么我们如果要处理单个线程的局部变量呢?可以用到ThreadLocal方法。

在Java中并行计算要涉及多线程。同样的,在一个JVM进程空间中,存在多个栈来记录多个线程的调用,但是这些线程共享堆中的对象,也就是说,对这些对象的修改,也需要加线程锁机制。

Java中实现多线程主要有两种方法:继承Thread类来创建线程,并提供run()方法,或者实施Runnable接口来创建线程,并提供run()方法。

如果二者同时存在,它会首先找子类的run方法,如果子类没有重写run,则再找Runnable接口的run方法。下面的例子,说明了这个结论,最后输出的是子类重写run方法的输出。

public class Test
{
	public static void main(String[] args)
	{
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("Runnable1:" + Thread.currentThread().getName());
//					System.out.println("Runnable2:" + this.getName());
				}
			}
		}) {
			@Override
			public void run() {
				while(true) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("Thread1:" + Thread.currentThread().getName());
					System.out.println("Thread2:" + this.getName());
				}
			}
		};
		thread.start();
	}
}

与Python对应的是,Java线程锁是通过同步机制来实现的,也就是synchronized方法。同一对象的synchronized方法只能同时被一个线程调用。其他线程必须等待该线程调用结束才能运行,排除了多线程同时修改全局变量的可能。

值得一提的是,Python中对应的全局变量用关键字global表示,而java和C/C++中用static来表示。

关于”协程“:

Python能实现多个线程,但是实际上无法充分利用系统资源,原因在于Python存在全局锁机制,简单来说,就是同一时刻在一个进程中只能有一个线程对数据进行操作。所以实现并行效果,采用多进程方法,比较好。

协程在一定程度上解决了这个问题。协程机制,就是在运行某个任务的过程中,我们可以随时中断,去执行另一任务,也可能随时再回来执行老任务。这在网络传输,IO过程中很有用,特别是对于两个不相关的任务来说,使用协程能达到异步执行的效果。

Java,不知道有没有这种机制。虽然xxxx,但是Java也不错的啦~~~在TIOBE编程语言排行榜一直稳坐头把交椅,这里面,无非Android开发给了Java这个优势。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 11:00:33

关于Python和Java的多进程多线程计算方法对比的相关文章

python并发编程(一):多线程,多进程

'''多进程(线程)编程: 1. 进程和线程 2. 并发与并行 3. 同步和异步 4. 阻塞和非阻塞 5. 进程/线程的调度模型''' # 综述 '''进程和线程: 1. 进程: 1) 是一个程序在数据集上的一次动态执行过程 2) 由程序, 数据集, 进程控制模块组成 2. 线程: 1) 是CPU的一个最小执行单元, 2) 线程的出现是为了降低进程间切换的消耗 3) 实现在一个进程内的并发 4) 由线程ID, 程序计数器, 寄存器集合, 堆栈组成 3. 进程和线程的关系: 1) 进程是线程的容器

Python 3 并发编程多进程之队列(推荐使用)

Python 3 并发编程多进程之队列(推荐使用) 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 可以往队列里放任意类型的数据 创建队列的类(底层就是以管道和锁定的方式实现): 1 Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递. 参数介绍: 1 maxsize是队列中允许最大项数,省略则无大小限制. 方法介绍: 1.主要

Python爬虫进阶五之多线程的用法

前言 我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理. 首先声明一点! 多线程和多进程是不一样的!一个是 thread 库,一个是 multiprocessing 库.而多线程 thread 在 Python 里面被称作鸡肋的存在!而没错!本节介绍的是就是这个库 thread. 不建议你用这个,不过还是介绍下了,如果想看可以看看下面,不想浪费时间直接看 multiprocessing 多进程 鸡肋点 名言: "Pyt

Golang、Php、Python、Java基于Thrift0.9.1实现跨语言调用

目录: 一.什么是Thrift? 1) Thrift内部框架一瞥 2) 支持的数据传输格式.数据传输方式和服务模型 3) Thrift IDL 二.Thrift的官方网站在哪里? 三.在哪里下载?需要哪些组件的支持? 四.如何安装? 五.Golang.Java.Python.PHP之间通过Thrift实现跨语言调用 1) Golang 客户端和服务端的实现及交互 2) python 客户端的实现与golang 服务端的交互 3) php 客户端的实现与golang 服务端的交互 4) java

11.python并发入门(part9 多线程模块multiprocessing基本用法)

一.回顾多继承的概念. 由于GIL(全局解释器锁)的存在,在python中无法实现真正的多线程(一个进程里的多个线程无法在cpu上并行执行),如果想充分的利用cpu的资源,在python中需要使用进程. 二.multiprocessing模块的简介. multiprocessing是python中用来管理多进程的包,与threading用法非常类似,它主要使用multiprocessing.Process对象来创建一个进程对象,该进程可以运行在python的函数中. 该Process(进程)对象

Java线程及多线程技术及应用

第6 章 Java线程及多线程技术及应用 6.1线程基本概念 1.进程和线程的基础知识 l 进程:运行中的应用程序称为进程,拥有系统资源(cpu.内存) l 线程:进程中的一段代码,一个进程中可以哦有多段代码.本身不拥有资源(共享所在进程的资源) 在java中,程序入口被自动创建为主线程,在主线程中可以创建多个子线程. 区别: 1.是否占有资源问题 2.创建或撤销一个进程所需要的开销比创建或撤销一个线程所需要的开销大. 3.进程为重量级组件,线程为轻量级组件 l 多进程: 在操作系统中能同时运行

Java中的多线程技术全面详解

本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上,"多进程"并不是真正的多个进程在同时执行,而是通过CPU时间分片,操作系统快速在进程间切换而模拟出来的多进程.我们通常把这种情况成为并发,也就是多个进程的运行行为是"一并发生"的,但不是同时执行的,因为CPU核数的限制(PC和通用寄存器只有一套,严格来说在同一时刻只能

[转帖]Windows和Linux对决(多进程多线程)

Windows和Linux对决(多进程多线程) https://blog.csdn.net/world_2015/article/details/44920467 太长了 还没看完.. 还是没太理解好呢.. 关于 windows 和 linux的东西 先放这里 晚上有时间仔细啃一下. 并行程序设计分为共享内存和消息驱动(其实就是分布式内存)两种, 共享内存:所有CPU共内存,所有CPU由一个操作系统控制的,例如Windows和Linux/UNIX,目前流行的多核.多CPU机器都是属于这种: 消息

Python 3 并发编程多进程之进程同步(锁)

Python 3 并发编程多进程之进程同步(锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,竞争带来的结果就是错乱,如何控制,就是加锁处理. 1.多个进程共享同一打印终端 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('%s is done' %os.g