2011-12-18 23 views
7

No puedo decidir si el siguiente deque es seguro para subprocesos.
En resumen, he creado una clase con un deque que muestra su contenido cada 1 segundo en un nuevo hilo (para que no pause el programa principal durante la impresión).
El deque se llena desde el hilo principal, por lo que básicamente DEBERÍA haber una posibilidad de colisión.
SIN EMBARGO, el deque se completa utilizando un método de clase, por lo que se accede esencialmente desde la propia instancia, por lo tanto, desde el mismo subproceso.
Aquí está el código simplificado:¿Este deque es seguro para subprocesos en python?

import threading 
import time 
from collections import deque 

class MyQueue(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     self.q = deque() 
     self.start() 

    def run(self): 
     # pop out queue items every 1 sec 
     # (please ignore empty deque for now) 
     while True: 
      print self.q.popleft() 
      time.sleep(1) 

    def add_to_q(self, val): 
     # this function is called from outside 
     self.q.append(val) 

# main 
# fill the queue with values 
qu = MyQueue() 
for i in range(1:100): 
    qu.add_to_q(i) 

Por lo tanto, aunque la adición y eliminación de elementos de la cola tienen lugar dentro de la instancia, ¿existe un riesgo debido a la adición de la función que se llama desde fuera de la instancia?

EDITAR:
Como necesito modificar elementos en mi deque, tuve que usar Deque. Lo que hago es: roatate() al elemento dado, sacarlo, modificarlo, empujarlo hacia adentro y girarlo() hacia su posición original.
menos que encuentre una forma de implementar la modificación de los artículos en una cola, voy a tener que atenerse a deque

+2

Si sólo necesita una cola de flujos seguros (no lo hago te veo usando cualquier función específica de deque), probablemente deberías usar la [cola incorporada segura para subprocesos] (http://docs.python.org/library/queue.html). – delnan

+0

David, gracias, agregué el bucle. delnan, excluí algunas características. El deque se está girando de vez en cuando para que los elementos se puedan abrir, modificar, volver a colocar y girar a su posición original. No encontré una forma de hacerlo con Queue – user1102018

+6

. Es imposible escribir código para probar si algo es seguro para la tarea y en su lugar debe leer la documentación o estudiar el código fuente. A menudo, si algo no es peligroso, funcionará casi todo el tiempo en un contexto enhebrado y luego explotará semanas más tarde. –

Respuesta

13

deque es seguro para subprocesos (http://docs.python.org/library/collections.html#deque-objects) para APPENDs y pops desde lados opuestos. Beneath here, los documentos solo mencionan que append() y popleft() son seguros para subprocesos.

Hay una implementación segura de subprocesos de la cola en sí. Entonces deberías usarlo a menos que tengas algunos requisitos extraños.

+4

No solo es deque threadsafe, sino que su rendimiento es mucho mayor que el módulo Queue.Lo valioso que el módulo Queue agrega es que 'get' puede bloquear. – amcnabb

+0

Only thread safe se agrega y aparece cuando lo leí (por ejemplo, no se puede usar 'len()' en los hilos, ¿verdad?) –

+0

definitivamente se lanza si itera y presiona al mismo tiempo – Brannon

2

Para obtener información no es un billete de Python referencia para deque hilo de seguridad (https://bugs.python.org/issue15329).

Title "aclarar qué métodos deque son thread-safe", la línea inferior es:

append de la deque(), appendleft(), pop(), popleft(), y len (d) las operaciones son seguras para hilos en CPython. Los métodos de adición tienen un DECREF al final (para los casos donde se ha establecido maxlen), pero este ocurre después de que se hayan realizado todas las actualizaciones de estructura y se hayan restaurado las invariantes , por lo que está bien tratar estas operaciones como atómico.

De todos modos, si usted no está 100% seguro y prefiere fiabilidad en el rendimiento, sólo hay que poner una cerradura como por print self.q.popleft() y self.q.append(val);)

Cuestiones relacionadas