Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/mman.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <wait.h>
- #include <string.h>
- #include <semaphore.h>
- #define BUFFER_SIZE 10
- typedef struct {
- int data [BUFFER_SIZE];
- int head;
- int tail;
- } Buffer;
- int main(void) {
- int i, data_size = sizeof (Buffer);
- shm_unlink("/shmtest_pl4_ex13");
- // Criar a zona de shared memory
- int fd = shm_open("/shmtest_pl4_ex13", O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
- ftruncate (fd, data_size);
- Buffer * shared_data = (Buffer *) mmap (NULL, data_size,
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- // Criação dos semáforos. São criados 3 semáforos.
- // - O primeiro garante que apenas um dos processos está a aceder à zona de
- // memória partilhada, logo começa a 1. (Exclusão mútua)
- // - O segundo garante que o consumidor fica bloqueado quando não há mais nada
- // para ler, visto que só passa a ser maior que 0 quando o produtor o incrementa
- // - O terceiro garante que só é utilizado o espaço disponível para o buffer,
- // começando portanto com o valor do BUFFER_SIZE
- const char *array_nome_semaforos[3];
- array_nome_semaforos[0] = "sema_pl4_ex13_exclusao_mutua";
- array_nome_semaforos[1] = "sema_pl4_ex13_itens";
- array_nome_semaforos[2] = "sema_pl4_ex13_espaco_disponivel";
- sem_t * array_semaforos [3];
- int valor_inicial_semaforo [3] = {1, 0, BUFFER_SIZE};
- // Delete dos semáforos
- for (i = 0; i < 3; i++) {
- sem_unlink (array_nome_semaforos[i]);
- }
- for (i = 0; i < 3; i++) {
- if ((array_semaforos[i] = sem_open (array_nome_semaforos[i], O_CREAT | O_EXCL, 0644, valor_inicial_semaforo[i])) == SEM_FAILED) {
- perror("Error creating the semaphore.");
- exit(1);
- }
- }
- // Inicialização de head e tail. Começam ambos a 0.
- shared_data->head = 0;
- shared_data->tail = 0;
- pid_t p1, p2;
- int pids[2];
- // Criação dos 2 filhos
- p1 = fork();
- if (p1 > 0) {
- pids[0] = p1;
- p2 = fork();
- pids[1] = p2;
- }
- // array_semaforos[0]: exclusão mútua
- // array_semaforos[1]: itens
- // array_semaforos[2]: espaço disponível no buffer
- if (p1 > 0 && p2 > 0) { // 1 consumidor
- for (i = 0; i < 30; i++) {
- sem_wait (array_semaforos[1]);
- sem_wait (array_semaforos[0]);
- printf ("[PAI]\n");
- if (shared_data->head > shared_data->tail) {
- //printf ("[PAI] i: %d; Li o valor %d\n", i, shared_data->data[shared_data->tail]);
- shared_data->tail++;
- }
- if(shared_data->head == 10 && shared_data->tail == 10){
- shared_data->head = 0;
- shared_data->tail = 0;
- }
- sem_post (array_semaforos[0]);
- sem_post (array_semaforos[2]);
- }
- } else { // 2 Produtores
- int increasing_value = 1;
- for (i = 0; i < 15; i++) {
- sem_wait (array_semaforos[2]);
- sem_wait (array_semaforos[0]);
- printf ("[FILHO]\n");
- //printf ("[FILHO] Escrevi o valor %d\n", increasing_value);
- shared_data->data[shared_data->head] = increasing_value;
- shared_data->head++;
- increasing_value++;
- sem_post (array_semaforos[0]);
- sem_post (array_semaforos[1]);
- }
- munmap (shared_data, data_size);
- close (fd);
- exit (1);
- }
- // Pai espera pelos processos filho só no fim para que executem todos
- // paralelamente
- for (i = 0; i < 2; i++) {
- waitpid (pids[i], NULL, 0);
- }
- // Delete dos semáforos
- for (i = 0; i < 3; i++) {
- sem_unlink (array_nome_semaforos[i]);
- }
- // Close e delete da shared memory
- munmap (shared_data, data_size);
- close (fd);
- shm_unlink("/shmtest_pl4_ex13");
- printf("Fim do programa.\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement