精华内容
下载资源
问答
  • 没有线程和睡眠假设您当前的程序流程如下:while True:data = read_sensors()command = process(data)motor_do(command)time.sleep(delay)然后你可以删除睡眠,如果最后次呼叫至少延迟几秒钟,则只调用motor_do.last...

    我认为你不需要线程,但我可能会误解你的要求,所以我将提出2个替代方案.

    >没有线程和睡眠

    假设您当前的程序流程如下:

    while True:

    data = read_sensors()

    command = process(data)

    motor_do(command)

    time.sleep(delay)

    然后你可以删除睡眠,如果最后一次呼叫至少延迟几秒钟,则只调用motor_do.

    last_call_time = -delay # to be sure that motor_do can be called the first time

    # "On Windows, [time.clock] returns wall-clock seconds elapsed since the first call to this

    # function, as a floating point number, based on the Win32 function QueryPerformanceCounter()

    # The resolution is typically better than one microsecond." (python 2.7 doc)

    # i.e. close to 0 on first call of time.clock()

    while True:

    data = read_sensors()

    command = process(data)

    motor_try(command)

    def motor_try(command):

    global last_call_time

    current_time = time.clock()

    # on win that works, on unix... you may want to take a look at the NB

    elapsed = current_time - last_call_time

    if elapsed >= delay:

    motor_do(command)

    last_call_time = current_time

    >使用线程(这是一个例子,我没有使用python 2.7进行线程/异步的经验,所以可能有更好的方法来做到这一点)

    假设您当前的程序流程如下:

    while True:

    data = read_sensors()

    command = process(data)

    motor_do(command) // this function sleeps and you CANNOT change it

    然后你必须启动1个线程,它只会异步地将命令推送到电机.

    import thread

    command = None

    command_lock = thread.allocate_lock()

    def main():

    thread.start_new_thread(motor_thread)

    global command

    while True:

    data = read_sensors()

    with command_lock:

    command = process(data)

    def motor_thread():

    while True:

    while not command: # just to be sure

    time.sleep(0.01)

    # small delay here (for instance, the time consumed by read_sensors + process)

    with command_lock:

    motor_do(command)

    command = None

    time.sleep(delay)

    注意:在Unix上,time.clock()返回处理器时间(=没有空闲时间),所以最好使用time.time()…除非更改系统时钟:“此函数通常返回非 – 如果在两次调用之间设置了系统时钟,则它可以返回比前一次调用更低的值.“ (python 2.7 doc)

    我不知道time.sleep()对系统时钟变化的反应.

    Python3:只使用time.monotonic()…或time.perf_counter().

    展开全文
  • java中多个用户在访问同一段代码的时候,后台会为每个请求分配个单独的线程来处理,线程之间是相互独立的,互不干扰,当然也可以相互通信。并发问题只有在多个线程之间可能修改同一资源的时候才会出现,解决...

            java中多个用户在访问同一段代码的时候,后台会为每一个请求分配一个单独的线程来处理,线程之间是相互独立的,互不干扰,当然也可以相互通信。并发问题只有在多个线程之间可能修改同一资源的时候才会出现,解决并发问题可以通过加锁来解决。好比说多个用户同时登陆一个系统时,都需要用到登陆的相关代码,是不会发生什么冲突的。好比说对一个财务系统,两个人同时对总钱数进行操作,一个加10块一个减100块,注意这两个操作是同时进行的,那系统就不知道是加还是减了,这是并发问题。加锁解决就是,在一个请求开始对这条记录操作时,其它的请求就不能对它操作了,直到现在正在进行的操作完成。

            多线程并发的处理,这里指的是服务器端,也就是 Java 的处理,与页面无关。

           首先,当多个请求同时到达服务器时,服务器会分配线程来执行每个请求(如果请求数量太多,能用的线程有限,则会进行排队)。所以请求和请求之间首先是一个线程隔离的环境。

           每个线程都会按照同样的顺序执行同样的代码(这里简单的不考虑分支),在执行代码的过程中,线程会访问和操作各种各样的对象和变量。所以这里就有一个问题:我怎么知道多个线程会不会访问到同一个对象,或者同一个变量呢?如果这样的事情发生了,可能会产生什么后果呢?

            在详细解释这个问题之前,首先需要明确一个简单的原则:任何对象都可以被任意多个线程访问,这是代码的自由性决定的。但更重要的是,我们可以让对象主动掌控线程对自己的访问。

         最简单的控制方式就是 synchronized,意即同时只允许一个线程访问,其它线程必须先等待。当 synchronized 用在方法上时,表示同一时间只允许一个线程执行这个方法。

           那么是否意味着服务器上的所有方法都必须是synchronized的呢?不是。当一个方法执行时,所有的变量和参数都会保存在一个叫做堆栈的内存空间,这个内存空间是线程独享的,所以线程之间不会相互冲突。例如:

    public void hello(String name) {

    public void hello(String name) {
    	String greetings = "Hello, " + name;
    	System.out.println(greetings);
    }
    

    }
            当多个线程执行 hello() 方法时,每个线程都会在自己的堆栈中存放 name 参数和 greetings 变量。其中 greetings 变量是在方法内定义的,一个线程中的 greetings 变量与另一个线程中的 greetings 变量将是完全隔离的,不会相互影响。

            堆栈是线程独享的,但是放入堆栈的内容则未必。像上面的例子,greetings 变量是线程自己创建的,所以其它线程访问不到,但 name 参数则未必,有可能多个线程在执行这个方法时,收到的 name 参数是同一个对象。这时候如果方法里面要修改这个对象,那就要小心了。

    展开全文
  • 在mp库当中,跨进程对象共享有三种方式,第种仅适用于原生机器类型,即python.ctypes当中的类型,这种在mp库的文档当中称为sharedmemory方式,即通过共享内存共享对象;另外种称之为server process,即有一个...

    继续写关于Python

    multiprocessing的使用手记,继上次的进程模型之后,这次展开讨论一下multiprocessing当中的跨进程对象共享的问题。

    在mp库当中,跨进程对象共享有三种方式,第一种仅适用于原生机器类型,即python.ctypes当中的类型,这种在mp库的文档当中称为shared

    memory

    方式,即通过共享内存共享对象;另外一种称之为server process

    即有一个服务器进程负责维护所有的对象,而其他进程连接到该进程,通过代理对象操作服务器进程当中的对象;最后一种在mp文档当中没有单独提出,但是在其

    中多次提到,而且是mp库当中最重要的一种共享方式,称为inheritance

    ,即继承,对象在

    父进程当中创建,然后在父进程是通过multiprocessing.Process创建子进程之后,子进程自动继承了父进程当中的对象,并且子进程对这

    些对象的操作都是反映到了同一个对象。

    这三者共享方式各有特色,在这里进行一些简单的比较。

    首先是共享方式所应对的对象类型,看这个表:

    共享方式

    支持的类型

    Shared memory

    ctypes当中的类型,通过RawValue,RawArray等包装类提供

    Inheritance

    系统内核对象,以及基于这些对象实现的对象。包括Pipe, Queue,

    JoinableQueue, 同步对象(Semaphore, Lock, RLock, Condition, Event等等)

    Server process

    所有对象,可能需要自己手工提供代理对象(Proxy)

    这个表总结了三种不同的共享方式所支持的类型,下面一个个展开讨论。

    其中最单纯简单的就是shared

    memory这种方式,只有ctypes当中的数据类型可以通过这种方式共享。由于mp库本身缺少命名的机制,即在一个进程当中创建的对象,无法在另外一

    个进程当中通过名字来引用,因此,这种共享方式依赖于继承,对象应该由父进程创建,然后由子进程引用。关于这种机制的例子,可以参见Python文档

    当中的例子 Synchronization types like locks,

    conditions and queues,参考其中的test_sharedvalues函数。

    然后是继承方式。首先关于继承方式需要有说明,继承本质上并不是一种对象共享的机制,对象共享只是其副作用。子进程从父进程继承来的对象并不一定是

    共享的。继承本质上是父进程fork出的子进程自动继承父进程的内存状态和对象描述符。因此,实际上子进程复制

    了一份

    父进程的对象,只不过,当这个对象包装了一些系统内核对象的描述符的时候,拷贝这个对象(及其包装的描述符)实现了对象的共享。因此,在上面的表当中,只

    有系统内核对象,和基于这些对象实现的对象,才能够通过继承来共享。通过继承共享的对象在linux平台上没有任何限制,但是在Windows上面由于没

    有fork的实现,因此有一些额外的限制条件

    ,因此,在Windows上面,继承方式是几乎无法用的。

    最后就是Server Process这种方式。这种方式可以支持的类型比另外两种都多,因为其模型是这样的:

    server process模型

    在这个模型当中,有一个manager进程,负责管理实际的对象。真正的对象也是在manager进程的内存空间当中。所有需要访问该对象的进程都

    需要先连接到该管理进程,然后获取到对象的一个代理对象(Proxy object),通常情况下,这个代理对象提供了实际对象的公共函

    的代理,将函数参数进行pickle,然后通过连接传送到管理进程当中,管理进程将参数unpickle之后,转发给相应的实际对象

    的函数,返回值(或者异常)同样经过管理进程pickle之后,通过连接传回到客户进程,再由proxy对象进行unpickle,返回给调用者或者抛出

    异常。

    很明显,这个模型是一个典型的RPC(远程过程调用)的模型。因为每个客户进程实际上都是在访问manager进程当中的对象,因此完全可以通过这

    个实现对象共享。

    manager和proxy之间的连接可以是基于socket的网络连接,也可以是unix

    pipe。如果是使用基于socket的连接方式,在使用proxy之前,需要调用manager对象的connect函数与远程的manager进程建

    立连接。由于manager进程会打开端口接收该连接,因此必要的身份验证是需要的,否则任何人都可以连上manager弄乱你的共享对象。mp库通过

    authkey的方式来进行身份验证。

    在实现当中,manager进程通过multiprocessing.Manager类或者BaseManager的子类实现。

    BaseManager提供了函数register注册一个函数来获取共享对象的proxy。这个函数会被客户进程调用,然后在manager进程当中执

    行。这个函数可以返回一个共享的对象(对所有的调用返回同一个对象),或者可以为每一个调用创建一个新的对象,通过前者就可以实现多个进程共享一个对象。

    关于这个的用法可以参考Python文档

    当中的例子“Demonstration of how to create and

    use customized managers and proxies”。

    典型的导出一个共享对象的代码是:

    ObjectType object_

    classObjectManager(multiprocessing.managers.BaseManager):pass

    ObjectManager.register("object",lambda: object_)ObjectType

    object_

    class ObjectManager(multiprocessing.managers.BaseManager): pass

    ObjectManager.register("object", lambda: object_)

    注意上面介绍proxy对象的时候,我提到的“公共函数”四个字。每个proxy对象只会导出实际对象的公共函数。这里面有两个含义,一个是“公

    共”,即所有非下划线开头的成员,另一个是“函数”,即所有callable的成员。这就带来一些限制,一是无法导出属性,二是无法导出一些公共的特殊函

    数,例如__get__,

    __next__等等。对于这个mp库有一套处理,即自定义proxy对象。首先是BaseManager的register可以提供一个

    proxy_type作为第三个参数,这个参数指定了哪些成员需要被导出。详细的使用方法可以参见文档当中的第一个例子。

    另外manager还有一些细节的问题需要注意。由于Proxy对象不是线程安全的,因此如果需要在一个多线程程序当中使用proxy,mp库会为

    每个线程创建一个proxy对象,而每个proxy对象都会对server

    process创建一个连接,而manager那边对于每个连接都创建一个单独的线程来为其服务。这样带来的问题就是,如果客户进程有很多线程,很容易会

    导致manager进程的fd数目达到ulimit的限制,即使没有达到限制,也会因为manager进程当中有太多线程而严重影响manager的性

    能。解决方案可以是一个进程内cache,只有一个单独的线程可以创建proxy对象访问共享对象,其余线程只能访问该进程当中的cache。

    一旦manager因为达到ulimit限制或者其他异常,manager会直接退出,遗憾的是,这时候已经建立的proxy会试图重新连接

    manager – 但是它已经不存在了。这个会导致客户进程hang在对proxy的函数调用上,这个时候,目前除了杀掉进程没有找到别的办法。

    另外proxy使用socket的方式比较tricky,因此和内置的socket库有很多冲突,比如

    socket.setdefaulttimeout(Python Issue

    6056

    )。在setdefaulttimeout调用了之后,进程当中所有通过socket模块建立的socket都是被设置为unblock模式的,但是mp

    库并不知道这一点,而且它总是假设socket都是block模式的,于是,一旦调用了setdefaulttimeout,所有对于proxy的函数调

    用都会抛出OSError,错误代码为11,错误原因是非常有误导性的“Resource temporarily

    unavailable”,实际上就是EAGAIN。这个错误可以通过我提供的一个patch

    来补救(这个patch当中还包含其他的一些修复,所以请自行查看并修改该patch)。

    由于以上的一些原因,server

    process模式作为一个对象的共享模式,能够提供最为灵活的共享方式,但是也有最多的问题。这个在使用过程当中就靠自己去衡量了。目前我们的系统对于

    数据可靠性方面要求不高,丢失数据是可以接受的,但是也只用这种模式来维护统计值,不敢用来维护更多的东西。

    展开全文
  • Android多进程

    2021-06-06 08:53:55
    、开启多进程方式通过在AndroidManifest文件中指定四大组件的process属性开启多进程process属性值以":"开头的进程属于当前应用的私有进程,否则为全局进程开启多进程后,application会次创建,进程间不共享内存...

    一、开启多进程方式

    通过在AndroidManifest文件中指定四大组件的process属性开启多进程

    process属性值以":"开头的进程属于当前应用的私有进程,否则为全局进程

    开启多进程后,application会多次创建,进程间不共享内存,所以单例失效,线程同步机制失效等

    二、进程间通信方式

    Intent Bundle(Activity,Service,BroadcastReceiver)

    文件

    Messenger,AIDL,Binder

    Socket

    ContentProvider

    Bundle

    传递序列化数据,实现了Parcelable,Serializable接口的对象

    文件

    通过ObjectOutputStream将序列化对象写入文件,通过ObjectInputStream反序列化存储

    到文件的对象

    适用于无并发,数据交换实时性不高场景

    Messenger,AIDL,Binder

    Messenger

    Messenger底层利用Aidl和Handler实现

    服务的串行处理客户端请求,不适合处理大量并发请求。

    作用主要是传递消息,不能处理跨进程方法调用。

    AIDL

    Aidl支持的数据类型

    int、long、double、float、char、boolean,String,Charsequence

    ArrayList,HashMap,里面每个元素都被AIDL支持

    实现了Parcelable接口的对象

    aidl接口

    编写aidl文件,服务端客户端aidl文件及目录名要一致

    服务端

    创建service,实现aidl接口,客户端回调接口通过RemoteCallbackList保存在服务端

    service中

    RemoteCallbackList通过ArrayMap存储客户端回调,由于key是binder对象,服务端和客

    户端回调的底层Binder对象是同一个,所以可以通过比较Binder对象找到服务端存储的回调。

    客户端

    绑定服务端service,绑定成功后将服务端返回的Binder转化(asInterface)为AIDL接口

    asInterface方法内部判断如果服务端客户端处于同一进程,则返回服务端Stub对象,否

    则返回服务端Stub.Proxy

    客户端绑定成功后,通过linkToDeath方法监听服务端Binder是否死亡。

    如果服务异常终止,则调用unlinkToDeath,然后重新绑定。

    Socket

    服务端

    通过ServerSocket监听特定端口,调用accept获取到连接到服务端的Socket

    通过getInputStream接收客户端消息和getOutputStream发送消息

    ServerSocket serverSocket = new ServerSocket(8383);

    Socket socket = serverSocket.accept();

    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

    reader.readLine();//读取客户端消息

    writer.write(serverMsg);//发送服务端消息到缓存

    writer.flush();//将消息缓存发送到客户端

    或者使用PrintWriter(设置autoFlush为true)的printlin方法代替BufferedWriter的write,flush。

    客户端

    通过Socket与服务端建立连接

    通过getInputStream接收服务端消息和getOutputStream发送消息

    Socket socket = new Socket("localhost", 8383);

    socket非null则表示连接到服务端

    读写方式和服务端一样。

    适用于网络通信,同一网段的设备间通信

    ContentProvider

    适用于进程间数据共享

    展开全文
  • python多进程间通信与接口间调用

    千次阅读 2020-12-29 09:03:42
    最近在写个小机器人的小项目,将比较耗时且繁琐的任务交由机器人处理...flow.png进程进程使用python内置的multiprocessing模块,它提供了个Process类来代表一个进程对象。创建子进程时,只需要传入个执行...
  • 我想做的是这样:class MyClass:def __init__(self):self.x = 0self.y = 1for i in range(10):exec ("obj{} = MyClass()".format(i))通过循环,我可以创建类的多个实例,因此当我调用Python Shell obj1时,它会返回...
  • 多个进程可以实现并发效果,当我们的程序中存在多个进程的时候,在某些时候,就会让程序的执行速度变快。在linux c语言中创建线程使用的fork函数,而Python就需要借助响应的模块、multiprocess模块仔细说来,...
  • 我已经阅读了大多数处理文档和一些关于调用类方法的文章,但是我还有一个额外的复杂性,即ClassA对象都有一个指向另一个类型(ClassB)的同一个实例的属性,它们可以向/从中添加/删除自身或其他对象。我知道共享状态...
  • 单例模式定义确保某个类只有个实例,而且自行实例化并向整个系统提供这个实例单例模式使用场景确保某个类有且只有对象的场景,避免产生多个对象消耗过多资源,或者某种类型的对象应该有且只有个。...
  • 多进程与守护进程

    2020-12-28 19:46:34
    [TOC]# **多进程和守护进程**## **multiprocessing模块介绍**python中的线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了...
  • 之前学习了多线程以及线程池,他们在执行I/O密集的程序的时候,性能是很高的,但是如果我们有大量的CPU密集型工作的程序,现在想利用多个CPU的优势运行的更快,应该怎么解决呢?这时候,就不能使用多线程了,而是...
  • 大概概况了线程使用中的方法,文章链接如下:今天开始会开启python多进程的内容,大家看过前面文章的应该都知道python中的GIL的存在,也就是线程的时候,同一时间只能有一个线程在CPU上运行,而且是单个CPU上...
  • Linux中使用C语言的fork()函数创建子进程的实例教程、fork入门知识个进程,包括代码、...一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到...
  • 在进入进程的学习之前, 一定需要先了解个应用程序是如何开启一个进程的, 以及操作系统对进程是如何进行分配资源的, 进程、线程、进程池、进程三态、同步、异步、并发、并行、串行的概念也要非常的明确, 下面将...
  • 6.2 ZeroMQ多进程和混合语言编程使用ZeroMQ的一个最大的好处是我们可以用不同的语言来写不同的进程。这样我们就可以部署一个node.js写的进程发消息来向用python写的进程发消息和请求服务。在这例子中,我们使用...
  • 1、同步调用同步调用是最基本的调用方式,对象b中的方法直接调用对象a的方法,这时候程序会等待对象a的方法执行完返回结果之后才会继续往下走。代码如下:public class A {public void methodA(){System.out....
  • (5.0分)【其它】1、编写一个程序,随机产生60-99的整数,写入到.txt文件中,再从文件中读取出来,并在屏幕上进行显示。 2、编写一个程序,统计**.txt中出现字母的个数、数字的个数、空格的字数,以及行数,除此之外.txt...
  • Java中创建多进程

    千次阅读 2021-02-12 09:42:51
    我们常常听到的比较是如何创建线程,很少听到如何创建多进程,今天我们来讲解一下如何创建多进程ProcessBuilder类ProcessBuilder类是J2SE 1.5在Java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供...
  • 刚好自己正在做个升级程序,主程序是一个进程,升级程序是一个进程,我把所有的与升级服务端的交互全部放在了升级程序中,所以当升级程序从服务端获取版本号与本地进行比较时,主程序需要进入等待阶段。...
  • 个进程都有两个堆栈:用户空间堆栈,内核空间堆栈 在这个过程中就发生了 CPU 上下文切换,整个过程是这样的: 1、保存 CPU 寄存器里原来用户态的指令位 2、为了执行内核态代码,CPU 寄存器需要更新为...
  • 多进程服务器端

    2021-03-16 18:22:06
    之前打下了理论基础,现在才是开始学习构建实际服务器的知识。 0.1 进程概念及应用 利用之前学习到的内容,我们可以构建按序向...而且网络程序中数据通信时间比CPU运算时间占比更大,因此,向多个客户端提供服务是
  • 01 线程工作在开始讲今天的正文之前,先给大家介绍一个概念「线程工作」,这概念可能有的人听过,也可能有的人平常工作中就是这么做的。我再来给大家讲讲这概念,所谓的「线程工作」就是同时做好几件事情...
  • 如果执行成功,这方法返回一个Process对象,如果执行失败,将抛出一个IOException错误。下面让我们来看一个简单的例子。// Test1。java文件import java。io。*;public class Test{ public static voi...
  • 多进程就是启用多个进程同时运行,由于进程是线程的集合,而且进程是由个或多个线程构成,所以多进程的运行意味着有大于或等于进程数量的线程在运行。 Python多进程的优势 根据这节线程基本原理了解到,由于进程...
  • 调用对象的finalize方法来释放对象占据的内存空间~java中垃圾回收以前听老师讲好像是内存满了他才去做次整体垃圾回收,在回收垃圾的同时会调用finalize方法....
  • python多进程和多线程是大家会重点了解的部分,因为很多工作如果并没有前后相互依赖关系的话其实顺序并不是非常的...就内存而言,已知进程是在执行过程中有独立的内存单元的,而多个线程是共享内存的,这是多进程...
  • C++多线程编程(10)类行为和线程处理1.C++对象4种作用域类型:局部作用域、函数作用域、文件作用域、类作用域程序分成多个进程,每个进程有自己的文本、数据和堆栈片段。每个程序有自己的堆。为了让进城访问另个进程...
  • Java多进程编程

    2021-02-12 09:42:53
    1.Java进程的创建Java提供了两种方法用来启动进程或其它程序:(1)使用Runtime的exec()方法(2)使用ProcessBuilder的start()方法1.1 ProcessBuilder ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类...
  • 导读热词比较好奇python对于多进程中copy on write机制的实际使用情况。目前从实验结果来看,python 使用multiprocessing来创建多进程时,无论...示例举例子,假设主进程读取了一个大文件对象的所有行,然后通过m...
  • java并行执行多个任务

    千次阅读 2021-02-26 15:16:37
    java并行执行多个任务:最近做项目中,有个任务需要实现并发编程,个人参考了下网上的实现,自己实现了下并发方法,并且增加了简单的说明,希望的有需要的朋友有些帮助。import java.util.UUID;import java.util....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 548,385
精华内容 219,354
关键字:

多个进程调用同一个对象