miércoles, 24 de octubre de 2012

Hilos En C++


#include
#include

#include
#include
#include

#include
#include
#include
#include

#include
#include

/*
 * Diagrama de precedencia:
 *
 *              inicial()
 *                 |
 *                 |
 *                /|\
 *               / | \
 *              /  |  \
 *             /   |   \
 *            /    |    \
 *           P1    P2    P3
 *            \    |    /
 *             \   |   /
 *              \  |  /
 *               \ | /
 *                \|/
 *                 |
 *                 |
 *               final()
 *
 */

union semun {
    int val;                    /* value for SETVAL */
    struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
    unsigned short int *array;  /* array for GETALL, SETALL */
    struct seminfo *__buf;      /* buffer for IPC_INFO */
};

pid_t pid_hijo1;
pid_t pid_hijo2;
pid_t pid_hijo3;
pid_t pid_hijo4;

key_t key_shared;

int id_heap;
int *mini_heap = NULL;
int sem_id;

// Estructura de 100 bytes
class Mensaje
{
public:
    Mensaje()
    {
        a = 0;
        b = 0;
        c = 0;
        d = 0;
        e = 0;
        f = 0;
        g = 0;
        h = 0;
        i = 0;
        j = 0;
        k = 0;
        l = 0;
        a2 = 0;
        b2 = 0;
        c2 = 0;
        d2 = 0;
        e2 = 0;
        f2 = 0;
        g2 = 0;
        h2 = 0;
        i2 = 0;
        j2 = 0;
        k2 = 0;
        l2 = 0;
        z = 0;
    }

    int a;
    int b;
    int c;
    int d;
    int e;
    int f;
    int g;
    int h;
    int i;
    int j;
    int k;
    int l;
    int a2;
    int b2;
    int c2;
    int d2;
    int e2;
    int f2;
    int g2;
    int h2;
    int i2;
    int j2;
    int k2;
    int l2;
    int z;
};

Mensaje * mensaje;

// plantilla para liberar con más robustez
template
void delete_ptr(T* ptr)
{
    if(ptr)
    {
        delete ptr;
        ptr = NULL;
    }
}

// iniciar semaforo compartido (solo el proceso padre)
int set_semvalue(void)
{
    union semun sem_union;

    sem_union.val = 1;
    if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return(0);
    return(1);
}

// liberar semaforo compartido (solo el proceso padre)
void del_semvalue(void)
{
    union semun sem_union;
   
    if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
        fprintf(stderr, "Failed to delete semaphore\n");
}

// intenta bloquear el semaforo compartido
bool lock(void)
{
    bool retorno = false;

    struct sembuf sem_b;
   
    sem_b.sem_num = 0;
    sem_b.sem_op = -1; /* P() */
    sem_b.sem_flg = SEM_UNDO;
    if (semop(sem_id, &sem_b, 1) == -1) {
        //fprintf(stderr, "semaphore_p failed\n");
        retorno = false;
    }
    else
        retorno = true;
   
    return retorno;
}

// intenta liberar el semaforo compartido
bool unlock(void)
{
    bool retorno = false;

    struct sembuf sem_b;
   
    sem_b.sem_num = 0;
    sem_b.sem_op = 1; /* V() */
    sem_b.sem_flg = SEM_UNDO;
    if (semop(sem_id, &sem_b, 1) == -1) {
        //fprintf(stderr, "semaphore_v failed\n");
        retorno = false;
    }
    else
        retorno = true;
       
    return retorno;
}

// El proceso padre crea la memoria compartida y el semaforo
void inicial()
{
    id_heap = shmget (key_shared, sizeof(int)*100, 0777 | IPC_CREAT);
    if (id_heap == -1)
    {
        std::cout << "No consigo Id para memoria compartida" << std::endl;
        exit (0);
    }

    mini_heap = (int *)shmat (id_heap, (char *)0, 0);
    if (mini_heap == NULL)
    {
        std::cout << "No consigo memoria compartida" << std::endl;
        exit (0);
    }
   
    std::cout << "Memoria compartida creada" << std::endl;
   
    ///////// SEMAFORO
   
    sem_id = semget(key_shared, 1, 0777 | IPC_CREAT);
   
    if(!set_semvalue())
    {
        std::cout << "Error al iniciar semáforo" << std::endl;
        exit (0);
    }
   
    ////////////////////
   
    // Memoria dinamica local
    mensaje = new Mensaje();
    mensaje->z = 0;
   
    // copiar a zona compartida
    memcpy (mini_heap, mensaje, sizeof(*mensaje));
   
    // liberamos la copia local
    delete_ptr(mensaje);
}

// el proceso padre libera las zonas compartidas
void final()
{
    int estadoHijo;
   
    for(int i=0 ; i<4 i="i" p="p">    {
        wait (&estadoHijo);

        if (WIFEXITED(estadoHijo) != 0)
        {
            assert(101 <= WEXITSTATUS(estadoHijo) && WEXITSTATUS(estadoHijo) <= 104);
            //printf ("Padre : Mi hijo ha salido. Devuelve %d\n", WEXITSTATUS(estadoHijo));
        }
    }
    /////////////////////////////////////////////////////////
   
    mensaje = reinterpret_cast(mini_heap);
    std::cout << "mensaje->z = " << mensaje->z << std::endl;
   
    // se espera 10000
    assert(mensaje->z == 10000);
   
    //////////////////////////////////////////////////////////
   
    del_semvalue();
   
    //////////////////////////////////////////////////////////
    // liberamos memoria compartida
    shmdt ((char *)mini_heap);
    shmctl (id_heap, IPC_RMID, (struct shmid_ds *)NULL);
   
    std::cout << "Memoria compartida liberada" << std::endl;
}

// los procesos hijos se asocian a la zona compartida y a su semaforo
void inicia_proceso_hijo()
{
    std::cout << "Asociandose a la memoria compartida" << std::endl;

    id_heap = shmget (key_shared, sizeof(int)*100, 0777 );
    if (id_heap == -1)
    {
        std::cout << "No consigo Id para memoria compartida" << std::endl;
        exit (0);
    }

    mini_heap = (int *)shmat (id_heap, (char *)0, 0);
    if (mini_heap == NULL)
    {
        std::cout << "No consigo memoria compartida" << std::endl;
        exit (0);
    }
   
    //////////////////////////////////////////////////////
   
    // asociarse al semaforo ya creado
    sem_id = semget(key_shared, 1, 0777);
}

// Los procesos hijso se desasocian de la memoria compartida al salir.
void termina_proceso_hijo()
{
    std::cout << "Desasociandose a la memoria compartida" << std::endl;
    if (id_heap != -1)
        shmdt ((char *)mini_heap);
}

// P2
void proceso2()
{
    mensaje = reinterpret_cast(mini_heap);
   
    int i=0;
    while( i<10000 p="p">    {
        if(lock())
        {
            mensaje->z++;
            unlock();
            i++;
        }
        //sleep(0.5);
    }
}

// P3
void proceso3()
{
    mensaje = reinterpret_cast(mini_heap);
   
    int i=0;
    while( i<10000 p="p">    {
        if(lock())
        {
            mensaje->z++;
            unlock();
            i++;
        }
        //sleep(0.5);
    }
}

// P4
void proceso4()
{
    mensaje = reinterpret_cast(mini_heap);
   
    int i=0;
    while( i<10000 p="p">    {
        if(lock())
        {
            mensaje->z--;
            unlock();
            i++;
        }
        //sleep(0.5);
    }
}

/*
 * FIXME: Lo suyo es hacer los fork() con un for(;;) en función del
 * número de cores, que se sabe facilmente con OpenMP:
 *
 *  num_cores = omp_get_num_procs();
    max_threads = omp_get_max_threads();
 *
 */
int main()
{
    key_shared = ftok ("/bin/ls", 33);
    if (key_shared == -1)
    {
        std::cout << "No consigo clave para memoria compartida" << std::endl;
        exit(0);
    }
   
    pid_hijo1 = fork();
    if (pid_hijo1 > 0)
    {      
        inicial();
       
        pid_hijo2 = fork();
        if(pid_hijo2 > 0)
        {
            pid_hijo3 = fork();
            if(pid_hijo3 > 0)
            {
                pid_hijo4 = fork();
                if(pid_hijo4 > 0)
                {
                    // para hacer más procesos secuencialmente
                }
                else
                {
                    inicia_proceso_hijo();
                    proceso4();
                    termina_proceso_hijo();
                    exit (104);  
                }
            }
            else
            {
                inicia_proceso_hijo();
                proceso3();
                termina_proceso_hijo();
                exit (103);
            }
        }
        else
        {
            inicia_proceso_hijo();
            proceso2();
            termina_proceso_hijo();
            exit (102);
        }
       
        final();
    }
    else
    {
        exit (101);
    }
   
    return 0;
}

Código del Peluquero Dormilón en C++


#include
#include
#include
 void graficar();

char SB, op; /*SB ='1' indica ocupada, '0' vacia */
 int SC[6], i, j, cc, orden, t1; /* las sillas llevaran el turno */

void main(){
 textmode(C80);
 textbackground(0);
 for(i=0; i<6 clientes="clientes" formateo="formateo" i="i+1)SC[i]=0;" lugares="lugares" p="p"> SB='1';
 cc=0;
 orden=0;
 do{
 clrscr();
 cout<<"\n\n\n\tCODIGO DEL BARBERO DORMILON\n";
 cout<<"\n\t I= Ingreso de un nuevo cliente\n";
 cout<<"\n\t T= Terminar la atencion a un cliente\n";
 cout<<"\n\t F= Finalizar el programa\n";
 graficar();
 op=getch();
 if(op=='i' || op=='I')
 {
 cc=0;
 if(SB=='0')cout<<"\n\tBARBERO TRABAJANDO";
 else cout<<"\n\tBARBERO EN SU SILLA, DURMIENDO";

if(SB=='1'){SB='0'; cout<<"\n\nSr Cliente, TIENE QUE DESPERTAR AL BARBERO"; }
 else{
 for(i=0; i<6 i="i+1){</p"> if(SC[i]==0){cout<<"\nSr Cliente, Pase Ud y ubiquese en la silla: "< orden=i; break;}
 }/*fin del for*/

/*Se verifica lugares ocupados*/
 for(i=0; i<6 i="i+1)if(SC[i]!=0)cc=cc+1;</p"> if(cc<6 asigna="asigna" cc="cc" el="el" le="le" orden="orden" p="p" proximo="proximo" se="se" turno="turno"> }/*del else por barbero dormido*/
 cout<<"\nSr Cliente: Vea que hay: "< if(cc>5) cout<<"\nEstimado Cliente, en este momento no hay lugar para Ud, vuelva mas tarde\no pruebe en otra barberia";
 getch();
 }/*del if op ingreso del cliente */

if(op=='t' || op=='T')
 {
 t1=7;
 /*se elige el turno mas bajo !=0 */
 for(i=0; i<6 amp="amp" i="i" if="if" sc="sc" t1="SC[i];orden=i;}</p">
for(i=0; i<6 i="i" if="if" p="p" t1="t1"> cout<<"\nEL Cliente ubicado en la silla: " <
/* actualiza los turnos */
 for(i=0; i<6 i="i" if="if" p="p" sc="sc">
if(t1==7){
 SB='1';
 cout<<"\n\tNO HAY MAS CLIENTES; EL BARBERO SE VA A SU SILLA A DORMIR";
 }
 getch();
 }/*del if op*/
 }while (op!='f'&& op!='F');
 }/*del main*/

void graficar()
 { /*Este codigo solo corre en turbo c++ de Borland*/
 textbackground(11);textcolor(1);
 gotoxy(20,14);cprintf(" GRAFICO DEL BARBERO DORMILON ");
 textbackground(2);textcolor(15);
 gotoxy(20,15);cprintf(" ");
 gotoxy(20,16);cprintf(" [ ] Silla Barbero");
 if(SB=='1'){gotoxy(24,16);cprintf(" Zzzz..");}
 else {gotoxy(24,16);cprintf(" ]WORKING!!!");}
 gotoxy(20,17);cprintf(" ");
 gotoxy(20,18);cprintf("Sillas Clientes:[ ][ ][ ][ ][ ][ ]");
 gotoxy(20,19);cprintf(" Turnos: ");
 gotoxy(20,20);cprintf(" Ingrese Opcion: ");


for(i=0; i<6 i="i+1){</p"> if(SC[i]!=0){
 textbackground(6);
 gotoxy(37+(i*3),18); cprintf(" ");
 textbackground(2);
 gotoxy(37+(i*3),19); cprintf("%i", SC[i]);

}
 else { gotoxy(28+(i*4),33); cprintf(" "); }
 }

textbackground(0);
 gotoxy(20,50);
 }

Método de Ordenamiento


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ordenar_vector
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] num = new int[100];
            int n;
            int temp, j;

            Console.WriteLine("ingrese numero:");
            n = Convert.ToInt32(Console.ReadLine());

            for (int i = 0; i < n; i++)
            {
                Console.Write("Elemento" + "[" + (i + 1) + "]: ");
                num[i] = Convert.ToInt32(Console.ReadLine());
            }

            for (int i = 1; i < n; i++)
            {
                for (j = n - 1; j >= i; j--)
                {
                    if (num[j - 1] > num[j])
                    {
                        temp = num[j - 1];
                        num[j - 1] = num[j];
                        num[j] = temp;
                    }
                }
            }


            Console.WriteLine("Vector ordenado:");
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("Elemento " + "[" + (i + 1) + "]: " + num[i]);
            }

            string x = Console.ReadLine();
        }
    }
}