none
Sincronización y Mutex RRS feed

  • Pregunta

  • Hola,

    Mi problema es el siguiente:

    Leo por puerto serie un sensor que transmite datos cada cierto tiempo, para la lectura uso el evento:

    COM->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);

    Los datos que recibo los voy almacenando en una cola.

    Para procesar los datos de la cola uso un hilo independiente 

    void ProcessTh(){
    while(true){
    ProccessMethod(Dev);
    Thread::Sleep(RATE); 
    }}

    El problema es que cuando proceso los datos de la cola ésta se actualiza y no puedo procesar la información.

    He probado a usar mutex pero no consigo que funcione, no sé si los uso correctamente....

    ¿Cómo puedo impedir que al recibir datos por el puerto serie mientras estoy procesando los datos de la cola no se actualice? 

    Gracias!


    Liiid

    domingo, 3 de agosto de 2014 20:32

Respuestas

  • Hola.  Lo que debe hacer es aprender bien acerca de objetos de sincronización y programación de múltiples hilos.

    En el código que muestra, rápidamente veo que Circ_Buf es una variable que usted accede tanto del hilo que lee datos como del que procesa datos.  Esto quiere decir que Circ_Buf es un recurso compartido.  Todo recurso compartido debe accederse sincronizadamente.

    Como sus hilos pertenecen al mismo proceso, no es necesario usar mutex.  Puede usar un CRITICALSECTION (en C++).  Su equivalente en C++/CLI (o sea, .net) no es tan bonito como en C#.  Refiérase a este enlace para la definición de la clase Lock.  Eso sería el equivalente al lock de C#.

    Nótese, sin embargo, que hasta donde tengo entendido (porque no sé de C++/CLI), C++/CLI permite el uso de C++ directamente, así que si usted sabe sincronizar en C++ debería ser capaz de hacerlo con un CRITICALSECTION.


    Jose R. MCP
    Code Samples

    martes, 21 de octubre de 2014 13:56
    Moderador
  • Gracias por tu respuesta.

    Acabé solucionándolo con la clase Monitor, parecida a la Lock.

    Según leí en la documentación también podría haber usado mutex, aunque en otra parte del código y no donde probé al principio.

    Saludos.


    Liiid

    miércoles, 22 de octubre de 2014 14:07

Todas las respuestas

  • Hola, puedes poner algo más de código? 

    Muchas gracias


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    martes, 5 de agosto de 2014 11:57
  • Hola, 

    Para la lectura del puerto serie uso lo siguiente, cuando se activa el evento del puerto DataReceived:

    String^ message_port;
    if (COM != nullptr && COM->IsOpen){
    message_port = COM->ReadExisting();
    message_char = message_port->ToCharArray(0, message_port->Length);
    for each(char c in message_char){
    //add chars to the queue 
    while (Circ_Buf->AddQueue(c,queue_ptr) == 0){ //queue full
    Circ_Buf->Pop(queue_ptr, 1); //delete first item
    }
    }

    Y para el procesado de la información empleo un thread:

    void ProcessTh(){
    while(true){
    //mx.WaitOne();
    process_packet(device->Circ_Buf->queue_ptr, device->Message);
    Thread::Sleep(RATE); //repite cada período de muestreo
    //mx.ReleaseMutex();
    }
    }

    process_packet (Queue_Type^% queue_ptr, Packet^% result){
    unsigned short myCRC = 0, packetCRC = 0, packet_type = 0, numToPop = 0, counter = 0;
    array<char>^ packet = gcnew array<char>(100);
    char dataLength;

    if (Circ_Buf->Empty(queue_ptr)){
    return 0; //empty buffer
    }
    //find header
    for (numToPop = 0; numToPop+1 < Circ_Buf->Size(queue_ptr); numToPop+=1){
    if (HEADER_IMU == Circ_Buf->peekWord(queue_ptr,numToPop))
    break;
    }

    .... //continúa buscando campos del paquete

    }

    Gracias!


    Liiid

    miércoles, 6 de agosto de 2014 8:06
  • Hola.  Lo que debe hacer es aprender bien acerca de objetos de sincronización y programación de múltiples hilos.

    En el código que muestra, rápidamente veo que Circ_Buf es una variable que usted accede tanto del hilo que lee datos como del que procesa datos.  Esto quiere decir que Circ_Buf es un recurso compartido.  Todo recurso compartido debe accederse sincronizadamente.

    Como sus hilos pertenecen al mismo proceso, no es necesario usar mutex.  Puede usar un CRITICALSECTION (en C++).  Su equivalente en C++/CLI (o sea, .net) no es tan bonito como en C#.  Refiérase a este enlace para la definición de la clase Lock.  Eso sería el equivalente al lock de C#.

    Nótese, sin embargo, que hasta donde tengo entendido (porque no sé de C++/CLI), C++/CLI permite el uso de C++ directamente, así que si usted sabe sincronizar en C++ debería ser capaz de hacerlo con un CRITICALSECTION.


    Jose R. MCP
    Code Samples

    martes, 21 de octubre de 2014 13:56
    Moderador
  • Gracias por tu respuesta.

    Acabé solucionándolo con la clase Monitor, parecida a la Lock.

    Según leí en la documentación también podría haber usado mutex, aunque en otra parte del código y no donde probé al principio.

    Saludos.


    Liiid

    miércoles, 22 de octubre de 2014 14:07