Ayuda con hilos en C

Iniciado por codX, 24 Enero 2020, 00:37 AM

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

codX

Hola gente del foro, tengo un pequeño código que no puedo hacer funcionar. consta de un cronometro y musica, los cuales quiero ejecutar a la vez en dos hilos separados. Pero me pasa que, funciona simepre uno solo el thread de la musica, o el del cronometro. Alguien me puede ayudar por favor?
Este es el codigo, con libreria ncurses.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ncurses.h>
#include <pthread.h>
void ini_video();
void *cronometro(void *args);
void *musica(void *arg);
void ejecuta_threads();

int main()
{
ini_video();
ejecuta_threads();
return 0;
}

void ejecuta_threads()
{
pthread_t th0, th1;

pthread_create(&th0, NULL, (void *)&cronometro, NULL);
pthread_create(&th1, NULL, (void *)&musica, NULL);
pthread_join(th0, NULL);
pthread_join(th1, NULL);
}

void ini_video()
{
int filas,columnas;
initscr();
start_color();

// letras, fondo.
init_pair(1, 4, 2); // cronometro
init_pair(2, 0, 2); // fondo pantalla
cbreak();
noecho();
keypad(stdscr, true);
bkgd(COLOR_PAIR(2));
curs_set(0);
getmaxyx(stdscr, filas, columnas);
refresh();
}

void *cronometro(void *args)
{
int horas, minutos, segundos;

for(horas = 0; horas <= 2; horas++){
for(minutos = 0; minutos < 60; minutos++){
for(segundos = 0; segundos < 60; segundos++){
attron(A_BOLD | COLOR_PAIR(1));
mvprintw(5, 50, "%s %i:%i:%i", "Tiempo ->  ", horas, minutos, segundos);
napms(1000);
refresh();
}
}
attroff(A_BOLD | COLOR_PAIR(1));
}
return NULL;
}

void *musica(void *arg)
{
char *comando = "/usr/bin/play";
char *args[] = {"play", "-q", "donkey.ogg", "-t", "alsa", 0};

while(1)
execv(comando, args);

}

fary

Prueba a pausar el hilo principal, es decir, que no muera la función main.
Un byte a la izquierda.

codX

Fary, gracias por tu tiempo. Lo probaré

RayR

El problema es que execv(), como todas las funciones exec, crea un nuevo proceso que reemplaza al actual. Naturalmente, esto significa que cuando ejecutas execv(), el proceso original, con todos sus hilos, es finalizado, y lo único que queda ejecutándose es el comando.

Podrías crear un subproceso hijo (fork()), o bien, reemplazar el execv() por system(), pero el problema de fondo es estar invocando programas externos. Cualquier solución va a ser sucia y no óptima. Siempre es mucho mejor usar desde tu código alguna biblioteca para eso.

Si forzosamente quieres hacerlo con comandos, seguramente lo más sencillo sea que simplemente uses system() en lugar de execv(). En ese caso, deberías eliminar el while, o te será imposible cerrar el programa, a menos que mates el proceso. Fíjate si play acepta algún argumento para repetir indefinidamente el sonido, o escribe tú un script que lo haga, e invócalo desde system().