Sei sulla pagina 1di 3

CC3301 - Programación de Software de Sistemas

Auxiliar 6
Profesor: Luis Mateu
Auxiliar: Alexandra Ibarra - Carlos Contreras

4 de Octubre de 2019

1. Comparación de secuencias de DNA


Control 3 – Semestre Otoño 2013
La siguiente función resuelve el problema de comparación de secuencias de DNA. Esta función
recibe como parámetros un arreglo de secuencias DNA llamado secuencias, su tamaño n y 2 punteros
pi y pj con la dirección en donde dejar la posición de las 2 secuencias que más se parecen:
void mayorSimilitud(Dna *secuencias, int n, int *pi, int *pj) {
int i, j, min= MAXINT;
for (i = 1; i < n; i++) {
for (j = 0; j < i; j++) {
int similitud = compDna(secuencias[i], secuencias[j]);
if (similitud < min) {
min = similitud;
*pi = i; *pj= j;
}
}
}
}

Se dispone de una máquina con 8 cores y se le pide a Ud. modificar la función mayorSimilitud de
la pregunta anterior de modo que se usen de la mejor forma estos 8 cores para reducir el tiempo de
ejecución. Para ello Ud. debe emplear la siguiente metodologı́a. Al inicio de la función cree 8 threads
adicionales que se usarán para realizar las comparaciones y que llamaremos los threads comparadores.
Al finalizar preocúpese de enterrarlos apropiadamente. El thread principal1 (el que ejecuta mayorSi-
militud) se usa para alimentar a los threads comparadores con pares (i, j) de secuencias que se deben
comparar. Cada thread comparador espera hasta obtener del thread principal un par (i, j) de secuen-
cias, las compara, revisa si se trata del par más similar del momento y luego espera a recibir un nuevo
par. Por otra parte el thread principal se dedica a generar un par (i, j), espera a que se desocupe
algún thread comparador, se lo asigna y luego genera un nuevo par, espera un thread comparador,
se lo asigna, . . . , etc. Para realizar la sincronización use un mutex y una condición. En un thread
comparador no olvide devolver el mutex antes de llamar a compDna, si no, no habrá paralelismo y su
solución no reducirá el tiempo de ejecución.
#include <pthread.h>
#include <stdlib.h>

typedef struct { /* pueden ser variables globales */


Dna *secuencias;
pthread_mutex_t m;
int *pi, *pj;
int n;
int min;
1
El thread principal no necesita un procesador para correr, si tiene problemas con esto asuma que tiene 9 cores

1
Buffer *buf;
} Info;

typedef struct { int i, j; } Par;

// 8 consumidores
void *compFun(void *ptr) {
Info *info= (Info*)ptr;

for (;;) {
Par *par= get(info->buf);
if (par==NULL)
break;

// consumir par
int similitud= compDna(info->secuencias[par->i], info->secuencias[par->j]);

pthread_mutex_lock(&info->m);
if (similitud < info->min) { // debe hacerse con el mutex tomado
info->min = similitud;
*(info->pi) = par->i;
*(info->pj) = par->j;
}
pthread_mutex_unlock(&info->m);
free(par);
}
return 0;
}

// 1 productor
void mayorSimilitud(Dna *_secuencias, int _n, int *_pi, int *_pj) {
Info info;
info.secuencias= _secuencias;
info.n= _n;
info.pi= _pi;
info.pj= _pj;
info.min= MAXINT;
info.buf= makeBuffer(1); // o 5, 10, etc.
pthread_mutex_init(&(info.m), NULL);

pthread_t comps[8]; // Los threads comparadores

for (int k= 0; k<8; k++)


pthread_create(&comps[k], NULL, compFun, &info);

for (int i= 1; i<_n; i++) {


for (int j= 0; j<_n; j++) {
// producir par
Par *par = malloc(sizeof(Par));
par->i= i; par->j= j;
put(info.buf, par);
}
}

for (int k= 0; k<8; k++) // Termina los 8 comparadores


put(info.buf, NULL);
for (int k= 0; k<8; k++)
pthread_join(comps[k], NULL);
freeBuffer(info.buf);
}

2
2. Input / Output
Escriba la función void find() que recorre los directorios, comenzando por el directorio actual,
recursivamente. Debe escribir en su salida estándar el nombre de todos los directorios y subdirectorios
que encuentra. Imprima solo el nombre, no el path completo. Su implementación no debe seguir links
simbólicos. Para hacer el recorrido utilice la función chdir.
#include <stdio.h>
#include <dirent.h> /* Manejo de directorios */
#include <sys/stat.h> /* Funcion stat y lstat */
#include <string.h>
#include <unistd.h> /* Tipos y constantes estandar */

void printName(int ident, char *name) {


int i;
for(i = 0; i < ident; ++i)
printf("\t");
printf(" %s\n", name);
}

void find(int ident) {


DIR *current_dir;
struct dirent *this_entry;
struct stat status;

if ((current_dir=opendir("."))==NULL)
return; /* error */

for (this_entry = readdir(current_dir); this_entry != NULL; this_entry = readdir(current_dir)) {

if (strcmp(this_entry->d_name, "..") == 0 || strcmp(this_entry->d_name, ".") == 0)


continue; /* ignoramos la carpeta actual y su padre */

if (lstat(this_entry->d_name, &status) != 0)
continue; /* error */

if (!S_ISDIR(status.st_mode))
continue;

printName(ident, this_entry->d_name);

/* cambiamos el directorio al recien impreso */


chdir(this_entry->d_name);
find(ident+1);
chdir("..");
}

closedir(current_dir);

int main(int argc, char const *argv[]) {


find(0);
return 0;
}

Potrebbero piacerti anche