He hecho un programa C bastante simple para calcular los términos de la secuencia de Fibonacci, que estoy ejecutando en Ubuntu. Hice algunas estructuras de datos bastante torpes para que pueda hacer números enteros muy grandes, pero los detalles del programa no son terriblemente importantes, lo que importa es que el programa puede tardar bastante tiempo para realizar los cálculos.Ejecutando un programa C con múltiples hilos en el fondo cuando requiere la entrada del usuario
Por curiosidad, decidí que me gustaría hacer que el programa inicie el cálculo y luego permitir al usuario ingresar un personaje para ver qué tan avanzado está el cálculo. Entonces, en este caso, si el programa está calculando el n-ésimo término de la secuencia de Fibonacci y aún no está hecho, ingresar el número "1" hará que el programa emita el término k que está actualmente computando. Intenté hacer eso usando el siguiente enfoque.
El programa usa scanf para obtener un entero largo que representa el término de la secuencia que debe calcularse. El programa luego crea un hilo con la rutina que escribí para calcular e imprimir el enésimo término de Fibonacci, que sale una vez que ha terminado de hacerlo. Después de eso, el programa crea una variable entera que utilicé para almacenar la entrada y la inicializa para que tenga un valor distinto de cero. Luego ingresa continuamente en un bucle while siempre que int sea distinto de cero, y en cada iteración del bucle realiza un scanf ("% d", & i). Luego compara ese valor a 1, y si es 1, imprimirá el valor de un contador que configuré para seguir el progreso del cálculo de Fibonacci.
De todos modos, todo lo anterior funciona muy bien a pesar de ser terriblemente fuera de profundidad con cosas como hilos. Sin embargo, el problema que estoy teniendo es que cuando tengo que calcular, digamos, el término de la millonésima de la secuencia, el programa tarda varios minutos en terminar, y sería bueno simplemente ejecutarlo en segundo plano. Sin embargo, si pongo el proceso en segundo plano con ctrl + z y luego escribo bg, el proceso comienza pero inmediatamente se detiene nuevamente. Supongo que esto se debe a que constantemente requiere la entrada del usuario y, por lo tanto, se detiene hasta que recibe esa entrada.
Cualquier sugerencia sobre cómo evitar el problema anterior sería muy apreciada. No estoy especialmente preocupado por este tema específico (cálculo de los números de Fibonacci) ya que es solo un problema bastante aleatorio que elegí usar para el cálculo. Estoy más interesado en el problema general de crear una forma básica para que el usuario ingrese comandos en el programa, que luego el programa ejecuta en hilos separados, pero que aún permite al usuario ejecutar el programa en segundo plano si es necesario.
Disculpas por la pregunta bastante larga, y gracias de antemano por cualquier ayuda!
Phil
Editar: Por solicitud, añadí (una versión muy simplificada de) el código aquí. La idea básica es la misma: el programa inicia una computación larga en un nuevo hilo, luego realiza un ciclo de entrada con scanf. Ingresando 0 sale del programa, ingresando 1 muestra un contador que indica el progreso del cálculo. Me gustaría poder ejecutar el programa en segundo plano, pero como está pidiendo continuamente información, detiene el proceso de inmediato. Ignora el desbordamiento aritmético en el contador; mi programa actual tiene estructuras de datos para tratar este tipo de cosas, pero traté de simplificar mi código tanto como sea posible para la legibilidad.
//Simple program to test threading and input.
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 2
void *stuff();
int counter; //keeps track of the progress of the computation
int main(){
counter=1;
pthread_t threads[NUM_THREADS];
pthread_create(&threads[0], NULL, stuff, NULL);
//loop while the input is non-zero so that the program can
//accept commands
int input=10;
while(input){
input=10;
printf("Enter 0 to exit or 1 to display progress: ");
scanf("%d", &input);
if(input==1){
printf("Currently iterating for the %dth time.\n", counter);
}
}
return 0;
}
//Randomly chosen computation that takes a while.
void *stuff(){
long i,j,n=1000000000;
for(i=0; i<=n; i++){
for(j=0; j<=n; j++){
i*i*i*i*i*i*i*i*i*i*i;
j*j*j*j*j*j*j*j*j*j*j;
counter++;
}
}
printf("Done.\n");
pthread_exit(NULL);
}
En lugar de la larga descripción, puede considerar publicar su código :-) –
¡Punto tomado! Espero que esto aclare un poco las cosas. – ptmx
Sugiero usar un controlador de señal en lugar de entrada con 'scanf' ... Entonces' kill -SIGUSR1 'podría usarse para activar su informe, incluso si la aplicación está en segundo plano. –
JimR