Multi Threads y Creación de archivos.

Iniciado por Xephiro, 24 Abril 2015, 18:46 PM

0 Miembros y 1 Visitante están viendo este tema.

Xephiro

Estimados,

Tengo un problema para crear archivos de forma paralela.

tengo 5 hilos para crear N archivos (siempre sobre 10), pero por algún motivo no funciona como creo.

Dejo parte del código para explicarme mejor:

Primero creao los hilos y les doy la función con sus parametros a ejecutar (primer for) y luego los ejecuto cada uno de ellos (segundo for)

Código (csharp) [Seleccionar]
Thread[] ThreadsPool = new Thread[inter];
           for (int i = 0; i < inter; i++)
           {
               ThreadsPool[i] = new Thread(() => Func1(start, end, i));
           }

           for (int i = 0; i < inter; i++)
           {
               ThreadsPool[i].Start();
           }


A continuación muestro parte de la Func1

Código (csharp) [Seleccionar]

private static void Func1(long initial, long final, int index)
       {
           try
           {
               semaphore.WaitOne();
               ....

               stream = File.Create("D:/temp_"+i+".tmp"); // LINEA CON PROBLEMAS
               do
               {
                   ....
               }
               while (...);
           }
           finally
           {
               semaphore.Release();
           }
       }


Estoy utilizando un semaforo de capacidad 5, pero por algún motivo cuando ejecuto los threads, siempre tratan de crear el mismo archivo, por lo que el programa cae ya que mas de un hilo trata de sobre escribir al mismo tiempo.

Intente con un lock justo en ese tramo, pero el error se mantiene.

¿Alguna idea de que puede ser? ya que si comento la línea para crear el archivo el resto del código que tengo se ejecuta sin ningun problema.

kub0x

Buenas,

¿podrías aportar el mensaje de error obtenido al recibir la excepción? Por lo que veo cada thread recibe un identificador distinto asi que no veo problema alguno en la creación de los archivos ya que todos tendrían nombres distintos.

Por cierto, tienes que cerrar el stream(FileStream) después de trabajar con él. Aporta más código y te ayudaremos.

Saludos.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Xephiro

Cita de: kub0x en 24 Abril 2015, 19:00 PM
Buenas,

¿podrías aportar el mensaje de error obtenido al recibir la excepción? Por lo que veo cada thread recibe un identificador distinto asi que no veo problema alguno en la creación de los archivos ya que todos tendrían nombres distintos.

Por cierto, tienes que cerrar el stream(FileStream) después de trabajar con él. Aporta más código y te ayudaremos.

Saludos.

El mensaje que arroja es el siguiente:

Citar
"El proceso no puede obtener acceso al archivo 'D:\\temp_30.tmp' porque está siendo utilizado en otro proceso."

Esto ya me resulta extraño, ya que aun pasando indices a cada hilo, por algún motivo tratan de acceder a un mismo varios hilos.

kub0x

Es preferible que utilizes el bloque "using" ya que por defecto implementa la interfaz IDisposable utilizada para liberar los recursos del stream.

Código (csharp) [Seleccionar]
using (StreamWriter sw = new StreamWriter("D:/temp_"+i+".tmp"))

Sino pega el code y le echamos un vistazo.

Saludos.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Eleкtro

Cita de: Xephiro en 24 Abril 2015, 18:46 PMIntente con un lock justo en ese tramo, pero el error se mantiene.

Buenas

Deberías mostrar el código de ese intento que mencionas para poder analizar de que manera probaste a sincronizar los sub-procesos para evitar que ninguno de ellos ejecute el código del bloque utilizando la clausura SyncLock cómo has dicho haber intentado, pues podrías haberlo implementado incorrectamente.

De todas formas, y suponiendo que lo hayas hecho correctamente, también deberías mostrar todo el código referente al Stream ya que cabría la posibilidad de que no estés liberando ese flujo de datos, y cómo ya ha comentado @Kubox, debes cerrarlo o bien utilizando la clausura Using o también puedes utilizar un bloque Try/Catch/Finally para asegurarte de que al final de la ejecución de ese bloque llamas al método Stream.Dispose o en su defecto Stream.Close (el cual por defecto llama a Stream.Dispose).

Saludos