int main(int argc, char* argv[]) { if (argc <= 1) { cout << "Error: No hay direccion del archivo" << endl; return -1; } if (argc >= 3 && !strcmp(argv[1],"-t")) { for(int i = 2; i < argc; ++i) { /* Los hijos del proceso realizarán el interior del if, *termina en exit(0), para que los hijos no realicen el for */ if(!fork()) { procesa_xml(argv[i],i); // i representará el m_type con que enviará mensajes al buzón exit(0); } } // Semáforos para impresor-padre Semaforo mySemaphore; Semaforo sonSemaphore; struct tag { char tag_name[MAX_CHAR]; // Nombre de la etiqueta int cantidad_tag; // Cantidad de la etiqueta }; int share_mem_id = shmget(KEY, sizeof(tag)*BUFER_SIZE, 0700 | IPC_CREAT); // Memoria compartida int share_mem_id_i = shmget(KEY_i, sizeof(int), 0700 | IPC_CREAT); // Memoria compartida int* i_share = (int*) shmat( share_mem_id_i, NULL, 0 ); *(i_share) = 0; /* Codigo de hijo impresor */ if(!fork()) { const tag* const area = (tag*) shmat( share_mem_id , NULL, 0 ); cout << "\nConteo de etiquetas de los archivos en orden alfabetico\n" << endl; cout << left << setw(28) << "Nombre de la etiqueta" << "Numero de veces" << endl; cout.fill('_'); cout << left << setw(42) << ' ' << '\n' << endl; mySemaphore.wait(); // Espera la primera llamada del padre while(*(i_share) != -1){ for(int i = 0; i < *(i_share); ++i){ cout.fill(' '); cout << left << setw(28) << area[i].tag_name << right << setw(8) << area[i].cantidad_tag << endl; } sonSemaphore.signal(); // Signal al proceso padre mySemaphore.wait(); // Se queda esperando a la proxima estructura a ejecutar } cout.fill('_'); cout << left << setw(43) << ' ' << endl; sonSemaphore.signal(); exit(0); } /* Instrucciones que realizará el padre */ tag tmp; // Vectores que se utilizarán para el ordenamiento alfabético de las estructuras tag tagVec[argc]; bool flagVec[argc]; for(int i = 2; i < argc; ++i) { flagVec[i] = true; } // Llena los vectores con los primeros mensajes enviados por los hijos for(int i = 2; i < argc; ++i) { myMailbox.recibir(tmp.tag_name,MAX_CHAR,tmp.cantidad_tag,i,0); strcpy(tagVec[i].tag_name,tmp.tag_name); tagVec[i].cantidad_tag = tmp.cantidad_tag; } // Los mensajes de los hijos que tengan "END", indican que terminó su ejecución for(int i = 2; i < argc; ++i) { if(!strcmp(tagVec[i].tag_name,"END")) flagVec[i] = false; } tag* area = (tag*) shmat(share_mem_id , NULL, 0); char bandera = ' '; // Extrae la menor etiqueta y la envía a impresión bool finish = false; do { int index_menor_etiqueta = 2; for(int i = 3; i < argc; ++i) { if(flagVec[i]) { int comparacion = strcmp(tagVec[i].tag_name,tagVec[index_menor_etiqueta].tag_name); if( comparacion < 0 ) { // tagVec[i].tag_name es menor index_menor_etiqueta = i; } else if(comparacion == 0 && index_menor_etiqueta != i) { /* Como hay 2 etiquetas iguales, se pasará a sumar las etiqeutas a alguna de las 2 * luego, se pedirá la siguiente etiqueta (buzón) para que no hayan conflictos */ tagVec[index_menor_etiqueta].cantidad_tag += tagVec[i].cantidad_tag; myMailbox.recibir(tmp.tag_name,MAX_CHAR,tmp.cantidad_tag,i,0); strcpy(tagVec[i].tag_name,tmp.tag_name); if(!strcmp(tagVec[i].tag_name,"END")) flagVec[i] = false; tagVec[i].cantidad_tag = tmp.cantidad_tag; } } } if(bandera != tagVec[index_menor_etiqueta].tag_name[1] && bandera != ' '){ mySemaphore.signal(); sonSemaphore.wait(); *(i_share) = 0; } // Envía los datos a impresor strcpy(area[*i_share].tag_name,tagVec[index_menor_etiqueta].tag_name); area[*i_share].cantidad_tag = tagVec[index_menor_etiqueta].cantidad_tag; *(i_share) += 1; bandera = tagVec[index_menor_etiqueta].tag_name[1]; // Al sacar el menor del vector, se llama a la siguiente etiqueta myMailbox.recibir(tmp.tag_name,MAX_CHAR,tmp.cantidad_tag,index_menor_etiqueta,0); strcpy(tagVec[index_menor_etiqueta].tag_name,tmp.tag_name); if(!strcmp(tagVec[index_menor_etiqueta].tag_name,"END")) flagVec[index_menor_etiqueta] = false; tagVec[index_menor_etiqueta].cantidad_tag = tmp.cantidad_tag; bool tmp = true; for(int i = 2; i < argc; ++i){ if(flagVec[i]) tmp = false; } if(tmp) finish = true; } while(!finish); mySemaphore.signal(); sonSemaphore.wait(); // Envía el último estructura de etiquetas al impresor *(i_share) = -1; mySemaphore.signal(); sonSemaphore.wait(); shmdt(area); shmctl( share_mem_id, IPC_RMID, NULL ); shmctl( share_mem_id_i, IPC_RMID, NULL ); mySemaphore.destroy(); sonSemaphore.destroy(); } else { // Caso de un solo archivo procesa_xml_un_archivo(argv[1]); } myMailbox.destroy(); return 0; }
/* * destruye los ipc */ int main(int argc, char** argv) { Logger::init(PATH_LOG,argv[0]); //destruir mutex Semaforo mutex = Semaforo(PATH_IPC_MUTEX.c_str()); mutex.destroy(); (Logger::getLogger())->escribir(MSJ,"Mutex destruido."); //destruir sem museo lleno Semaforo museo_lleno = Semaforo(PATH_IPC_MUSEOLLENO.c_str()); museo_lleno.destroy(); (Logger::getLogger())->escribir(MSJ,"Semaforo de museo lleno destruido."); //obtener memoria compartida key_t key = ftok(PATH_IPC_SHM.c_str(),SHM); int shm_id = shmget(key,sizeof(MUSEO),0666); if (shm_id == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo obtener la memoria compartida para destruirla."); Logger::destroy(); exit(1); } MUSEO* museo_shm = static_cast<MUSEO*>(shmat(shm_id,0,0)); if (museo_shm == (MUSEO*)(-1)) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo inicializar la memoria compartida."); Logger::destroy(); exit(1); } //obtengo la cant de puertas int cantidad_puertas = museo_shm->cant_puertas; int res = shmdt(museo_shm); if (res < 0) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo desatachear la memoria compartida al inicializar."); Logger::destroy(); exit(1); } //elimino la memoria res = shmctl(shm_id,IPC_RMID,NULL); if (res == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo destruir la memoria compartida."); Logger::destroy(); exit(1); } (Logger::getLogger())->escribir(MSJ,"Memoria compartida destruida."); //eliminar colas de puertas static char puerta[MAX_DIG_PUERTA]; for (int i=0;i<cantidad_puertas;i++) { sprintf(puerta,"%d",i); //eliminar cola entrada key_t key = ftok(PATH_IPC_COLAENTRADA.c_str(),i); int id_cola = msgget(key,0666); if (id_cola == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo obtener la cola de entrada para la puerta "+puerta+" para eliminarla."); Logger::destroy(); exit(1); } int res = msgctl(id_cola,IPC_RMID,NULL); if (res == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo destruir la cola de entrada para puerta "+puerta+"."); Logger::destroy(); exit(1); } Logger::getLogger()->escribir(MSJ,string("Eliminada exitosamente cola de entrada para puerta ")+puerta+"."); //eliminar cola entrada respuesta key = ftok(PATH_IPC_COLAENTRADA_RESP.c_str(),i); id_cola = msgget(key,0666); if (id_cola == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo obtener la cola de entrada de respuesta para la puerta "+puerta+" para eliminarla."); Logger::destroy(); exit(1); } res = msgctl(id_cola,IPC_RMID,NULL); if (res == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo destruir la cola de entrada de respuesta para puerta "+puerta+"."); Logger::destroy(); exit(1); } Logger::getLogger()->escribir(MSJ,string("Eliminada exitosamente cola de entrada de respuesta para puerta ")+puerta+"."); //eliminar cola de salida key = ftok(PATH_IPC_COLASALIDA.c_str(),i); id_cola = msgget(key,0666); if (id_cola == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo obtener la cola de salida para la puerta "+puerta+" para eliminarla."); Logger::destroy(); exit(1); } res = msgctl(id_cola,IPC_RMID,NULL); if (res == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo destruir la cola de salida para puerta "+puerta+"."); Logger::destroy(); exit(1); } Logger::getLogger()->escribir(MSJ,string("Eliminada exitosamente cola de salida para puerta ")+puerta+"."); //eliminar cola salida respuesta key = ftok(PATH_IPC_COLASALIDA_RESP.c_str(),i); id_cola = msgget(key,0666); if (id_cola == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo obtener la cola de salida de respuesta para la puerta "+puerta+" para eliminarla."); Logger::destroy(); exit(1); } res = msgctl(id_cola,IPC_RMID,NULL); if (res == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo destruir la cola de salida de respuesta para puerta "+puerta+"."); Logger::destroy(); exit(1); } Logger::getLogger()->escribir(MSJ,string("Eliminada exitosamente cola de salida de respuesta para puerta ")+puerta+"."); } //eliminar cola de museo cerrado key = ftok(PATH_IPC_COLAMUSEOCERRADO.c_str(),COLA_MUSEO_CERR); int cola_museo_cerrado = msgget(key,0666); if (cola_museo_cerrado == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo obtener la cola de aviso de museo cerrado para eliminarla."); Logger::destroy(); exit(1); } res = msgctl(cola_museo_cerrado,IPC_RMID,NULL); if (res == -1) { (Logger::getLogger())->escribir(ERROR,std::string(strerror(errno))+" No se pudo destruir la cola de aviso de museo cerrado."); Logger::destroy(); exit(1); } Logger::getLogger()->escribir(MSJ,string("Eliminada exitosamente cola de de aviso de museo cerrado.")); (Logger::getLogger())->escribir(MSJ,"------------------------------------------------------"); Logger::destroy(); return 0; }