| Subcribe via RSS

Procesos en C: Crear un nuevo proceso con fork()

Octubre 26th, 2009 | No Comments » | Posted in C/C++, programacion

Siguiendo con los artículos sobre procesos voy a poner aquí un sencillo ejemplo para ilustrar el funcionamiento de la función fork().

Esta función es la que se encarga de crear un nuevo proceso dentro de un proceso. El nuevo proceso creado es una copia exacta del original, con la única diferencia que cada uno de ellos tiene su propio identificador de proceso (pid).

#include <stdio.h>
 
int main() {
	int pid;
 
	printf("PADRE: Soy el proceso padre y mi pid es: %d\n", getpid());
 
	pid = fork();
 
	// En cuanto llamamos a fork se crea un nuevo proceso. En el proceso
	// padre 'pid' contendrá el pid del proceso hijo. En el proceso hijo
	// 'pid' valdrá 0. Eso es lo que usamos para distinguir si el código
	// que se está ejecutando pertenece al padre o al hijo.
 
	if (pid) // Este es el proceso padre
	{
		printf("PADRE: Soy el proceso padre y mi pid sigue siendo: %d\n", getpid());
		printf("PADRE: Mi hijo tiene el pid: %d\n", pid);
	}
	else // Proceso hijo
	{
		printf("HIJO: Soy el proceso hijo y mi pid es: %d\n", getpid());
		printf("HIJO: mi padre tiene el pid: %d\n", getppid());
	}
}

En un próximo post explicaré cómo convertir el proceso hijo en un nuevo proceso totalmente diferente (con el conjunto de funciones ‘exec’). Esto nos permitirá lanzar un programa desde dentro de otro.


¿Necesitas ayuda con algún trabajo de clase? Entra en BuscoProfe.com

Tags: , , ,

Procesos en C: Ejemplo de un sencillo cronómetro con SIGALRM

Octubre 19th, 2009 | No Comments » | Posted in C/C++, programacion

Continuando con el artículo de la semana pasada sobre procesos en C hoy os dejo aquí un sencillo ejemplo de un cronómetro:

// Para las funciones pause y alarm:
#include <unistd.h>
// Para las constantes SIGALRM y similares
#include <signal.h>
 
#include <stdio.h>
 
// Esta es la función que se va a ejecutar cada vez que se reciba la
// señal SIGALRM
void contar_segundos() {
	// Usamos static para que se conserve el valor de "segundos"
	// entre cada llamada a la función
	static int segundos=0;
 
	segundos++;
	printf("Han pasado %d segundos.\n", segundos);
}
 
int main() {
	// Asociamos la señal SIGALRM a la función contar_segundos
	signal(SIGALRM, contar_segundos);
 
	// Ponemos en marcha un bucle
	while(1) {
		// Establecemos una alarma para dentro de un segundo
		alarm(1);
		// Pausamos la ejecución del programa para que 
		// se quede esperando a recibir una señal.
		pause();
	}
}

¿Necesitas ayuda con algún trabajo de clase? Entra en BuscoProfe.com

Tags: , , ,

Procesos en C: Señales (SIGINT)

Octubre 13th, 2009 | 1 Comment | Posted in C/C++, programacion

Desde hace un tiempo tengo la idea de escribir sobre el tema de procesos y señales en C.

Las señales se usan para la comunicación entre procesos y manipularlos. Un ejemplo muy conocido de señal es la señal SIGINT, que se envía cuando el usuario pulsa CTRL+C durante la ejecución de un programa. Cuando el programa que estamos ejecutando recibe esta señal finalizará su ejecución.

En el siguiente ejemplo vamos a ver cómo podemos hacer para que el programa realice alguna acción especial cuando el usuario pulse CTRL+C. La acción a ejecutar va a ser mostrar el mensaje: “¿Por qué me interrumpes?”:

// Para las funciones pause y alarm:
#include <unistd.h>
// Para las constantes SIGALRM y similares
#include <signal.h>
 
#include <stdio.h>
 
// Esta función es la que vamos a usar como controlador de la señal SIGINT
void despedida() {
	printf("------------------------\n");
	printf("¿Por qué me interrumpes?\n");
	printf("------------------------\n");
	raise(SIGTERM);
}
 
int main() {
 
	// Asociamos la señal SIGINT con la funcion "senal"
	signal(SIGINT, despedida);
 
	// Comenzamos un bucle que hará que el programa muestre sin
	// parar el mensaje "Nada nuevo por aquí"
	while(1) {
		printf("Nada nuevo por aquí.\n");
	}
}

En este programa, cuando el usuario pulse CTRL+C, en lugar de cerrarse directamente, se ejecutará la función que hemos asociado con esta señal (la funcion despedida).

La función despedida muestra el mensaje “¿Por qué me interrumpes?” y genera la señal SIGTERM (”raise” envía una señal al propio proceso). Si no hiciéramos esto el proceso no se detendría nunca (hasta que lo “matemos” con kill). Si te aburres haz la prueba con esta funcion:

void despedida() {
	printf("------------------------\n");
	printf("¿Por qué me interrumpes?\n");
	printf("------------------------\n");
}

Otra posibilidad es usar la función signal de nuevo para indicar al proceso que use la acción por defecto de SIGINT (SIG_DFL – Signal Default):

void despedida() {
	printf("------------------------\n");
	printf("¿Por qué me interrumpes?\n");
	printf("------------------------\n");
	signal(SIGINT, SIG_DFL); // Indicamos al programa que use la acción por defecto
	raise(SIGINT);
}

¿Pero por qué no podemos simplemente llamar a raise(SIGINT);?

Se podría pensar que bastaría con llamar a raise(SIGINT):

void despedida() {
	printf("------------------------\n");
	printf("¿Por qué me interrumpes?\n");
	printf("------------------------\n");
	raise(SIGINT);
}

El problema es que la señal SIGINT va a ser procesada por la función “despedida”. De esta forma, cuando pulsemos CTRL+C, se llamará a la función despedida. La función despedida genera de nuevo la señal SIGINT, que va a ser procesada de nuevo por ella misma. El resultado es que cuando pulsamos CTRL+c el proceso comenzará a ejecutar una y otra vez la función despedida mostrando el mensaje “¿Por qué me interrumpes?” sin parar.

¿Por qué? Cada vez que se pulse CTRL+C se ejecuta la función “despedida” en lugar de ejecutarse la acción por defecto (cerrar el programa).


¿Necesitas ayuda con algún trabajo de clase? Entra en BuscoProfe.com

Tags: , , ,

Introducción a la GSL (GNU Scientific Library) – Evaluar un polinomio

Octubre 23rd, 2008 | 1 Comment | Posted in C/C++, programacion

Recientemente he tenido que desarrollar un pequeño programa usando la librería GSL (GNU Scientific Library). Esta es una potente librería disponible en C para realizar complejos cálculos científicos. Este artículo va a servir como introducción a dicha librería.

Lo primero que necesitamos para trabajar con esta librería en Ubuntu es el paquete libgsl0-dev. Si no me equivoco el paquete libgsl0dbl, necesario para ejecutar programas hechos con esta librería, viene “de serie” en el sistema.

Vamos a ver el funcionamiento de la librería evaluando el polinomio: 4×2+3x+2 cuando x = 2:

/* ejemplo_gsl.c */
#include <stdio.h>
#include <gsl/gsl_poly.h>
 
int main (void)
{
  double coeficientes[] = { 2, 3, 4 };
  double x = 2;
  double resultado = gsl_poly_eval (coeficientes, 3, x);
  printf ("4*x2 + 3*x + 2 = %f\n", resultado);
  return 0;
}

El polinomio se evalúa usando la función gsl_poly_eval(), que tiene como parámetros:

- coeficientes: un array que contiene los coeficientes del polinomio.
- 3: es el tamaño del array de coeficientes.
- x: contiene el valor que queremos evaluar.

Para compilar el ejemplo bastaría con hacer:

gcc -o ejemplo_gsl ejemplo_gsl.c -lgsl -lgslcblas

Este programa daría como resultado:

4*x2 + 3*x + 2 = 24.000000
Tags: , , ,

Programación en C: Compilando con gcc

Octubre 16th, 2008 | No Comments » | Posted in C/C++, programacion

Voy a iniciar una serie de artículos sobre la compilación de programas en C con gcc. Esta serie de artículos estará centrada en la compilación en Linux.

NOTA: Si usas Ubuntu y no encuentras gcc en tu sistema echa un vistazo aquí.

Para el ejemplo vamos a usar el siguiente sencillo programa:

/* primero.c - Una versión del típico hola mundo */
#include <stdio.h>
 
int main()
{
	printf("Compilado con GCC\n");
	return 0;
}

Para compilar este sencillísimo programa basta con ejecutar la orden:

gcc -o primero primero.c

donde:

-o primero: la opción -o nos permite especificar el nombre del ejecutable que se va a generar. Si no especificamos nada el nombre que se genera por defecto es a.out.

primero.c: el fichero que contiene el código fuente del programa.

Compilando con dos ficheros fuente

Ahora supongamos que tenemos dos ficheros fuente:

primero.c:

#include <stdio.h>
 
int main()
{
	printf("Compilado con GCC\n");
	segundo();
	return 0;
}

segundo.c:

#include <stdio.h>
 
int segundo()
{
	printf("Función segundo\n");
}

Si probamos la orden anterior tendremos el un resultado similar a éste:

/tmp/ccuAuHGn.o: In function `main':
primero.c:(.text+0x1e): undefined reference to `segundo'

La forma correcta de compilar en este caso sería:

gcc -o primero primero.c segundo.c

Y si lo ejecutamos:

Compilado con GCC
Función segundo

Todo muy sencillito hasta ahora. En la próxima entrega veremos cómo compilar nuestro programa con librerías adicionales.

Tags: , , ,