int main(int argc, char *argv[]) { char buf[128]; key = ftok("server.c", 888); default_params(¶ms); parse_cmdline(argc, argv, ¶ms); fifo = open(params.fifo_path, O_RDWR); if (fifo < 0) die("open"); sem = semget(key, 0, 0); if (sem < 0) die("semget"); sem_op(0, -1); snprintf(buf, 128, "%s", params.message); write(fifo, buf, strlen(buf) + 1); sem_op(1, 0); sem_op(-1, -1); read(fifo, buf, 128); printf("Read from server: '%s'\n", buf); sem_op(0, 1); return 0; }
void lemipc(int ac, char **av) { t_info *info; info = init(ac, av); print_board(info->game, 0); while (is_last(info)) ; while (42) { sem_op(info->semid, -1); print_board(info->game, 1); is_dead(info); if (is_last(info)) shmclear(&info, 1); if (info->lead) find(info); else listen_lead(info); print_board(info->game, 0); sem_op(info->semid, 1); usleep(TIMEOUT); } shmclear(&info, 2); }
int main(int argc, char *argv[]) { FILE *fp; all_types *p_list; const char* filename; int idsem_sch_submit; int idsem_proc_table_mutex; if(argc < 2) { fprintf(stderr, "Usage: so_submit <all_types file>.\n"); exit(1); } // get a communication channel between the scheduler and so_submit using a semaphore if ((idsem_sch_submit = semget(SCH_SBMT_SEM_KEY, 1, IPC_CREAT|0x1ff)) < 0) { printf("Error obtaining the semaphore: %s\n", strerror(errno)); exit(1); } // start the mutex to provide only one read/write access if ((idsem_proc_table_mutex = semget(PROC_TABLE_MUTEX_SEM_KEY, 1, IPC_CREAT|0x1ff)) < 0) { printf("Error obtaining the semaphore: %s\n", strerror(errno)); exit(1); } filename = argv[1]; fp = fopen(filename, "r"); if(!fp) { fprintf(stderr, "Can't open specified file: <%s>.\n", filename); exit(1); } parse_process_list(&p_list, SHM_BASE_PROC_NUMBER, fp); fclose(fp); // get the process table access sem_op(idsem_proc_table_mutex, 0); sem_op(idsem_proc_table_mutex, 1); // add the processes to the index lists refresh_index_list(p_list, COEF_LIST_1_SHM_KEY, sjf_schd); refresh_index_list(p_list, COEF_LIST_2_SHM_KEY, large_slow_proc_schd); // push the all_types read into shared memory's all_types vector append_proc_list(p_list); // release the process table sem_op(idsem_proc_table_mutex, -1); // send a signal to the scheduler sem_op_nblock(idsem_sch_submit, -1); return 0; }
/** helper function for decrementing semaphore **/ int sem_wait(int sem_id, int index){ if(sem_op(sem_id, index, -1)==0){ printf("semaphore signal error\n"); return 0; } return 1; }
int shcon_unlock_sem (shcon_t* _shcon) { int tmp = 0; int ret = 0; struct sembuf _unlock_buf = { SEMSET_LOCK, +1, 0 }; if (_shcon == NULL || _shcon->sem == NULL) { ERR_PRINT (_EPTRNULL); ret = -1; return ret; } if (!_shcon->locked) { ret = 1; return ret; } tmp = sem_op (_shcon->sem, _unlock_buf, 1); if (tmp < 0) { ERR_FROM (); ret = tmp; } else { _shcon->locked = 0; } return ret; }
/************************************************************** * * semGive - Give a semaphore back. * * This routine gives a System V semaphore back. * * * RETURNS: * VOID * * Author Greg Brissey 6/24/94 */ void semGive(int id) /* int id - semaphore id */ { sigset_t signalMask; blockSignals(&signalMask); /* block signals while working on the semaphores */ sem_op(id, 1); unblockSignals(&signalMask); return; }
int main(int argc, char *argv[]) { int cmd = 0; char *buf; key = ftok("server.c", 113); default_params(¶ms); parse_cmdline(argc, argv, ¶ms); sem = semget(key, 0, 0); if (sem < 0) die("semget"); shm = shmget(key, params.shm_size, 0); if (shm < 0) die("shmget"); shm_data = shmat(shm, NULL, 0); sem_op(0, -1); if (!strcmp(params.message, "exit")) cmd = -1; ((int*)shm_data)[0] = cmd; buf = shm_data + sizeof(int); snprintf(buf, params.shm_size, "%s", params.message); sem_op(1, 0); sem_op(-1, -1); if (cmd >= 0) printf("Read from server: '%s'\n", buf); sem_op(0, 1); return 0; }
int shcon_add_sem_con (shcon_t* _shcon) { int tmp = 0; int ret = 0; struct sembuf _add_buf = { SEMSET_CON, +1, SEM_UNDO }; if (_shcon == NULL || _shcon->sem == NULL) { ERR_PRINT (_EPTRNULL); ret = -1; return ret; } tmp = sem_op (_shcon->sem, _add_buf, 1); if (tmp < 0) { ERR_FROM (); ret = tmp; } return ret; }
int main(){ printf("En este ejemplo un proceso va a poner en memoria una hilera de caracteres aleatorios. Se usan tres semaforos, uno para el area de memoria compartida y dos para que ambos procesos se avisen cuando se terminan de interactuar con la operacion de produccion/consumo.\n\n"); // inicializacíon de los semaforos int sem_id = semget(IPC_PRIVATE, 3, PERM|IPC_CREAT|IPC_EXCL); if(sem_id < 0){ printf("No pude obtener el semaforo.\n"); perror("RAZON"); exit(-1); } union semun { int val; struct semid_ds *buf; ushort * array; } argument; argument.val = 0; if(semctl(sem_id, SEMAFORO_PRODUCTOR, SETVAL, argument) < 0){ printf("Error al inicializar el contador del semaforo del productor.\n"); perror("RAZON"); exit(-1); }else{ printf("Inicializado el semaforo del productor. %s", get_time()); } if(semctl(sem_id, SEMAFORO_CONSUMIDOR, SETVAL, argument) < 0){ printf("Error al inicializar el contador del semaforo del consumidor.\n"); perror("RAZON"); exit(-1); }else{ printf("Inicializado el semaforo del consumidor. %s", get_time()); } argument.val = 1; // le doy permiso para que el hijo ponga el primer texto if(semctl(sem_id, SEMAFORO_SHM, SETVAL, argument) < 0){ printf("Error al inicializar el contador del semaforo de memoria.\n"); perror("RAZON"); exit(-1); }else{ printf("Inicializado el semaforo de memoria compartida. %s", get_time()); } // inicializacion de la memoria compartida int shm_id = shmget(IPC_PRIVATE, 512, PERM|IPC_CREAT|IPC_EXCL); if(shm_id < 0){ printf("No pude obtener la memoria compartida.\n"); perror("RAZON"); exit(-1); }else{ printf("Inicializada la memoria compartida %d. %s\n", shm_id, get_time()); } // struct para las operaciones struct sembuf oper_productor[1], oper_shm[1], oper_consumidor[1]; int f = fork(); if(f == -1) exit(1); if(f == 0){ //printf("I'm Luke\n"); int retval; char *shared_memory =(char*)shmat(shm_id,0,0); if(shared_memory == (void*)-1){ printf("Error al conectarse a la memoria compartida.\n"); perror("RAZON"); exit(-1); } while(1){ sleep(1); // 1 segundo entre cada envio para notar los cambios retval = sem_op(sem_id, SEMAFORO_SHM, oper_shm, -1); // wait shm //zona critica sprintf (shared_memory, "%s\n", rand_string(12)); retval = sem_op(sem_id, SEMAFORO_SHM, oper_shm, 1); // signal shm retval = sem_op(sem_id, SEMAFORO_PRODUCTOR, oper_productor, 1); // signal productor if(retval < 0){ printf("Error al realizar el signal de productor.\n"); perror("RAZON"); exit(-1); // hago esto por miedo a inanicion }else{ retval = sem_op(sem_id, SEMAFORO_CONSUMIDOR, oper_consumidor, -1); // wait consumidor if(retval < 0){ printf("Error al realizar el wait de consumidor.\n"); perror("RAZON"); exit(-1); // hago esto por miedo a inanicion } } } }else{ //printf("Luke, I'm your father\n"); int retval; char *shared_memory =(char*)shmat(shm_id,0,0); if(shared_memory == (void*)-1){ printf("Error al conectarse a la memoria compartida.\n"); perror("RAZON"); exit(-1); } while(1){ retval = sem_op(sem_id, SEMAFORO_PRODUCTOR, oper_productor, -1); // wait productor if(retval == 0){ retval = sem_op(sem_id, SEMAFORO_SHM, oper_shm, -1); // wait shm //zona critica printf ("En la memoria compartida hay: %s\n", shared_memory); retval = sem_op(sem_id, SEMAFORO_SHM, oper_shm, 1); // signal shm retval = sem_op(sem_id, SEMAFORO_CONSUMIDOR, oper_consumidor, 1); // signal consumidor if(retval < 0){ printf("Error al realizar el signal de consumidor.\n"); perror("RAZON"); exit(-1); // hago esto por miedo a inanicion } }else{ printf("Error al realizar el wait del productor.\n"); perror("RAZON"); exit(-1); // hago esto por miedo a inanicion } } } return 0; }
void sem_signal(int id) { sem_op(id, 1); }
void sem_wait(int id) { sem_op(id, -1); }
int main (int argc, char* argv[]) { pid_t fils[NB_FILS], pere = getpid(); //Variable qui stocke le pid de chaque processus int semid, shmid; //Identifiant des semaphores et segments de mémoire partagé char* nom = "main.c"; //Chaine de caractère pour générer la clé key_t cle; //La clé qui permet de générer l'id du semaphore pid_t *mem; //Pointeur vers le segment memoire partagé (qui contiendra la pid des fils) int i; /**** Creation du segment de memoire partagee ****/ shmid = cree_segment(2*sizeof(pid_t),nom,42); if(shmid == -1) { fprintf(stderr,"erreur création segment"); exit(EXIT_FAILURE); } /**** Création de l'ensemble des 2 semaphores ****/ if((cle = ftok(nom,44)) == -1) { //Génération de la clé printf("Erreur de ftok\n"); exit(EXIT_FAILURE); } if((semid = semget(cle,2,IPC_CREAT|0666)) == -1) { //Création de l'ensemble de semaphore perror("Erreur de semget"); exit(EXIT_FAILURE); } if(semctl(semid,0,SETVAL,2) == -1) { //On défini pour l'ensemble 0 la valeur 2 pour le semaphore printf("Erreur SETVAL à 2\n"); //Permet de régurer le nombre de client dans l'ascenseur exit(EXIT_FAILURE); } if(semctl(semid,1,SETVAL,1) == -1) { //On défini pour l'ensemble 1 la valeur 1 pour le semaphore printf("Erreur SETVAL à 1\n"); //Permet de gérer les écriture sur le segment de mémoire partagé exit(EXIT_FAILURE); } /**** Création des fils ****/ printf("Naissance des fils\n"); for (i=0; i<NB_FILS; i++) { fils[i] = fork(); if (fils[i] == 0) break; //Comme le fils sort du FOR directement après sa création, l'indice i correspond à son numéro de fils. } /********** Partie du programme pour le PERE **********/ if (pere == getpid()) { signal(SIGUSR1,SIG_IGN); //On ignore le signal SIGUSR1 /**** On se lie au segment de mémoire partagé en lecture seule***/ if ((mem = shmat(shmid,NULL,SHM_RDONLY)) == (pid_t*)-1) { perror("erreur ouverture segment"); exit(EXIT_FAILURE); } i = 0; printf("Je suis le pere, pid : %d\n\n", getpid()); /**** Boucle qui attend que tout les fils soient monté avec de fermer la programme ****/ while(i<NB_FILS) { sleep(1); int nbClient = 2 - semctl(semid,0,GETVAL); //On récupère le nombre de client qui sont montés i+=nbClient; //Et on incérmente le nombre de client total /**** Montée de l'ascenseur ****/ if(nbClient > 0) { printf("===== L'ascenseur monte ! =========="); if(nbClient == 1) { //Si on a qu'un seul client dans l'ascenseur, on ne fait descendre que lui printf("===> Le pid %d peut descendre \n", mem[0]); while(kill(mem[0],SIGUSR1)==-1); } else if(nbClient == 2) { //Sinon on fait descendre les 2 printf("===> Les pids %d et %d peuvent descendre\n", mem[1], mem[0]); while(kill(mem[0],SIGUSR1)==-1); while(kill(mem[1],SIGUSR1)==-1); } sleep(1); printf("===== L'ascenseur redescend ! ==========\n"); sleep(2); } } sleep(1); /**** Libération des SMP et de l'ensemble de sémaphore avant de terminer le programme ****/ shmdt(mem); detruire_segment(shmid); semctl(semid,0,IPC_RMID); } /********** Partie du programme pour les FILS **********/ else { int ordre=1, pid = getpid(); sleep(3); //Syncronisation avec le père /**** On demande le sémaphore pour monter dans l'ascenseur ***/ //Cette opération est bloquante, tant que l'on ne dispose pas du sémaphore. sem_op(semid,0, -1, 0); //On fait une opération P, pour prendre le sémaphore printf("----------- Fils %d ----------> \t", i); //On monte dans l'ascenseur signal(SIGUSR1,descente); //Définition du comportement pour le signal SIGUSR1 : appeler la fonction qui permet de descendre /**** On se lie au segment de mémoire partagé ***/ if ((mem = shmat(shmid,NULL,0)) == (pid_t*)-1) { perror("erreur ouverture segment"); exit(EXIT_FAILURE); } //On utilise le second sémaphore pour savoir si on pu écrire notre pid dans la première case ou dans la seconde. if (sem_op(semid,1, -1, IPC_NOWAIT)!=-1) memcpy(&(mem[0]), &pid, sizeof(pid)); else { memcpy(&(mem[1]), &pid, sizeof(pid)); ordre=2; } printf("%d\n", pid); //Affichage du pid du processus shmdt(mem); //Détachement du SMP while(descendre == 0); //On attend que l'ascenseur soit arrivé en haut pour descendre printf("<---------- Fils %d ----------- \n", i); //On descend if (ordre == 1) //Si on a pris le semaphore pour écrire dans le 1er emplacement de SMP sem_op(semid,1, 1, 0); // on le rend. sleep(1); sem_op(semid,0, 1, 0); //On libère le semaphore de l'ascenseur } return 0; }
int sem_unlock() { return sem_op(1); }
int sem_lock() { return sem_op(-1); }