Digamos que tengo un vector de N elementos, pero hasta n elementos de este vector tienen datos significativos. Un subproceso actualizador actualiza el elemento nth o n + 1st (luego establece n = n + 1), también comprueba si n está demasiado cerca de N y llama a vector :: resize (N + M) si es necesario. Después de la actualización, el hilo llama a varios hilos secundarios para leer hasta la enésima información y hacer algunos cálculos.Vector de STL y seguridad de hilo
Se garantiza que los hilos secundarios nunca cambien o eliminen datos (de hecho, no se eliminan datos) y el actualizador llama a los niños justo después de que finaliza la actualización.
Hasta ahora no ha ocurrido ningún problema, pero quiero preguntar si puede ocurrir un problema durante la reasignación de vector a un bloque de memoria más grande, si hay algunos subprocesos secundarios de trabajo de la actualización anterior.
¿O es seguro usar vector, ya que no es seguro para subprocesos, en un caso de multiproceso?
EDITAR: Dado que solo se realiza una inserción cuando el actualizador llama a vector :: resize (N + M, 0), ¿hay alguna posible solución a mi problema? Debido al gran rendimiento del vector STL, no estoy dispuesto a reemplazarlo por un vector bloqueable o, en este caso, ¿hay algún vector performant, conocido y sin bloqueos?
@ James McNellis: Sí. Ese es un buen consejo.Puedo hacer la reasignación yo mismo. En realidad, los vectores se envuelven dentro de una clase que contiene un puntero al vector. No es shared_ptr, pero puedo construir fácilmente un nuevo vector más grande, copiar elementos del anterior, eliminarlo. Entonces, ¿cuál es la forma más rápida de copiar un bloque de memoria grande? CopyMemory()? –
¿No sería una solución más simple usar 'std :: deque' en lugar de un vector? Eso evita las reasignaciones por completo, al tiempo que ofrece un rendimiento casi a la par con el vector. – jalf
@jalf: No creo que sea seguro usar un 'std :: deque' porque las reasignaciones no son la única preocupación. No hay garantía de que 'std :: deque :: operator []' no verifique el tamaño ni ninguna otra contabilidad interna del 'deque', por lo que existe la posibilidad de una condición de carrera en la que el consumidor llame al operador' [] ', que lee el estado interno mientras el productor está agregando datos, lo que modifica el estado interno. –