Soy nuevo en subprocesos en c. Mi código tiene un hilo que aumenta un contador y ocasionalmente (al azar) otro hilo lee ese contador. Usé mutex en este código, pero mi código siempre me da un valor igual a 1. Aunque usé pthread_mutex_unlock pero parece que el valor se bloquea para siempre. ¿Qué debo hacer para solucionar el problema?

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <pthread.h>
///////////////////////////

long int count=0;
int RunFlag=0;
pthread_mutex_t mtx;

void *readfun(void *arg)
{
    while (RunFlag==0)
    {
        pthread_mutex_lock(&mtx);
        count=count+1;
        pthread_mutex_unlock(&mtx);
    }

}
void *printfun(void *arg)
{
    int RadnTime=0;
    for (int j=0;j<4;j++)
    {
        RadnTime=rand()%3+1;
        sleep(RadnTime);

        printf("The current counter after %d seconds is: ",RadnTime);
        pthread_mutex_lock(&mtx);
        printf("%d\n",count);
        pthread_mutex_unlock(&mtx);
    }



}

void main ()
{
    pthread_t thread1;
    pthread_t thread2;

    pthread_mutex_init(&mtx, NULL);

    pthread_create(&thread1,NULL,readfun,NULL);
    pthread_create(&thread2,NULL,printfun,NULL);

    //stop the counter
    RunFlag=1;

    pthread_exit(NULL);
}
0
user1492588 13 dic. 2016 a las 20:47

2 respuestas

La mejor respuesta

Está configurando RunFlag inmediatamente después de que se crean los dos subprocesos, por lo que readfun apenas tiene tiempo para ejecutarse. RunFlag=1; debería estar al final de printfun.


Hasta donde yo sé, no se garantiza que leer y escribir en RunFlag sea atómico, por lo que el acceso también debe estar protegido. No veo que ocurra ningún problema aquí (dados los valores en cuestión), pero está entrando en un territorio de comportamiento indefinido.


Tus funciones no devuelven nada a pesar de que se declaran devolviendo void*. Agrégales return NULL;.


Finalmente, el segundo %d debería ser %ld ya que count es un long int.


Tenga en cuenta que

pthread_mutex_t mtx;
pthread_mutex_init(&mtx, NULL);

Puede ser reemplazado con

pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
1
ikegami 13 dic. 2016 a las 18:38

1) También tienes carrera de datos ya que dos están accediendo RunFlag. Por lo tanto, debe protegerlo con primitivas de sincronización (como mutex o usar un semáforo).

Pero no necesita el RunFlag para este propósito. Ya que puede usar un bucle infinito en el hilo readfun() y luego simplemente llamar a _exit() desde el hilo printfun() para salir de todo el proceso.

2) Las funciones de subprocesos deben devolver un puntero para cumplir con pthread_create() . Pero sus funciones de hilo no devuelven nada. Puede agregar return NULL; al final de ambas funciones del hilo.

Tenga en cuenta el desbordamiento de entero firmado, ya que count podría desbordarse.

1
P.P 13 dic. 2016 a las 18:19