Desta vez, implementaremos as importantes operações de
send e receive utilizando semáforos! Esta implementação simples demonstra como dois threads um
receiver e outro
sender podem simular o ambiente para utilizar as funções
send e
receive.
CÓDIGO-FONTE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
#define FANCIEST_MSG 15
#define BUSY_WAIT 3
#define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO )
sem_t *empty_msgs, *full_msgs;
pthread_mutex_t buffer_mutex;
int buffer[BUFFER_SIZE];
int buffer_head = 0;
int dummy = 0;
void *sender (void *arg);
void *receiver (void *arg);
void send (int msg);
void receive();
void print_buffer();
void sem_close_n_unlink(sem_t *semId, char *semName);
void error_exit(const char*);
char *rand_str(char *mystr, int size);
int main() {
srand(time(NULL));
int res;
pthread_t my_sender, my_receiver;
void *thread_result;
// start w/ N EMPTY MESSAGES << sem empty messages.
// produces has an item to give to the consumer?
// sem_wait(&sem_empty_msg)
// sem_post(&sem_full_msg)
res = pthread_mutex_init(&buffer_mutex,NULL);
if(res != 0){
perror("Inicializacao de mutex falhou");
exit(EXIT_FAILURE);
}
char *empty_sem_name, *full_sem_name;
empty_msgs = sem_open(rand_str(empty_sem_name,8),O_CREAT,0,BUFFER_SIZE);//, FILE_MODE,BUFFER_SIZE);
if (empty_msgs == SEM_FAILED) {printf ("sem_failed.\n");}
full_msgs = sem_open(rand_str(full_sem_name,8),O_CREAT,0,0);
// if (full_msgs == SEM_FAILED) {printf ("sem_failed.\n");}
res = pthread_create(&my_sender,NULL,sender,(void *)&dummy);
if (res != 0){
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&my_receiver,NULL,receiver,(void *)&dummy);
if (res != 0){
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
res = pthread_join(my_sender, &thread_result);
if (res != 0){
perror("Thread join failed");
exit(EXIT_FAILURE);
}
//destroy mutex
pthread_mutex_destroy(&buffer_mutex);
// closing and unlink semaphores
sem_close_n_unlink(empty_msgs, empty_sem_name);
sem_close_n_unlink(full_msgs, full_sem_name);
return 1;
}
void *sender (void *arg) {
int id = *(int *) arg; // irrelevante pois supomos apenas um sender
int msg;
while(1){
msg = rand () % FANCIEST_MSG;
sleep(rand() % BUSY_WAIT);
printf("sender has a msg: %d\n", msg);
sem_wait(empty_msgs); //check whether we can send
send(msg);
sem_post(full_msgs); //receive remembers to receive
}
}
void *receiver (void *arg) {
int id = *(int *) arg;
while(1){
sem_wait(full_msgs);
sleep(rand() % BUSY_WAIT);
receive();
sem_post(empty_msgs);
}
}
void send(int msg) {
pthread_mutex_lock(&buffer_mutex);
printf("sender inserted msg %d in buffer\n", msg);
buffer[buffer_head] = msg;
buffer_head++;
print_buffer();
pthread_mutex_unlock(&buffer_mutex);
}
void receive() {
int msg;
pthread_mutex_lock(&buffer_mutex);
printf("receiver removing msg %d in buffer\n", buffer[buffer_head - 1]);
msg = buffer[buffer_head - 1];
buffer_head--;
print_buffer();
pthread_mutex_unlock(&buffer_mutex);
}
void print_buffer(){
int index;
printf("buffer is... ");
for (index = 0; index < buffer_head; index++){
printf(". %d .", buffer[index]);
}
printf("\n");
}
void error_exit(const char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
char *rand_str(char *mystr, int size) {
if ((mystr = calloc(size + 1, sizeof(char))) == NULL) {
printf("callor error.\n");
return NULL;
}
int aux;
for (aux = 0; aux < size ; aux++) {
mystr[aux] = (char)((rand() % 23) + 'a');
}
mystr[aux] = '\0';
return mystr;
}
void sem_close_n_unlink(sem_t *semId, char *semName) {
if (sem_close (semId) == -1) {
printf ("sem_close failed\n");
return;
}
if (sem_unlink (semName) == -1) {
printf ("sem_unlink failed\n");
return;
}
printf ("closed and unlinked semaphore\n");
}
TESTES
sender has a msg: 5
sender inserted msg 5 in buffer
buffer is... . 5 .
sender has a msg: 2
sender inserted msg 2 in buffer
buffer is... . 5 .. 2 .
sender has a msg: 1
sender inserted msg 1 in buffer
buffer is... . 5 .. 2 .. 1 .
receiver removing msg 1 in buffer
buffer is... . 5 .. 2 .
sender has a msg: 13
sender inserted msg 13 in buffer
buffer is... . 5 .. 2 .. 13 .
sender has a msg: 3
sender inserted msg 3 in buffer
buffer is... . 5 .. 2 .. 13 .. 3 .
receiver removing msg 3 in buffer
buffer is... . 5 .. 2 .. 13 .
sender has a msg: 9
sender inserted msg 9 in buffer
buffer is... . 5 .. 2 .. 13 .. 9 .
receiver removing msg 9 in buffer
buffer is... . 5 .. 2 .. 13 .
sender has a msg: 10
sender inserted msg 10 in buffer
buffer is... . 5 .. 2 .. 13 .. 10 .
sender has a msg: 0
receiver removing msg 10 in buffer
buffer is... . 5 .. 2 .. 13 .
sender inserted msg 0 in buffer
buffer is... . 5 .. 2 .. 13 .. 0 .
sender has a msg: 4
receiver removing msg 0 in buffer
buffer is... . 5 .. 2 .. 13 .
sender inserted msg 4 in buffer
buffer is... . 5 .. 2 .. 13 .. 4 .
receiver removing msg 4 in buffer
buffer is... . 5 .. 2 .. 13 .
sender has a msg: 0
sender inserted msg 0 in buffer
buffer is... . 5 .. 2 .. 13 .. 0 .
receiver removing msg 0 in buffer
buffer is... . 5 .. 2 .. 13 .
receiver removing msg 13 in buffer
buffer is... . 5 .. 2 .
sender has a msg: 11
sender inserted msg 11 in buffer
buffer is... . 5 .. 2 .. 11 .
sender has a msg: 9
receiver removing msg 11 in buffer
buffer is... . 5 .. 2 .
sender inserted msg 9 in buffer
buffer is... . 5 .. 2 .. 9 .
receiver removing msg 9 in buffer
buffer is... . 5 .. 2 .
sender has a msg: 14
sender inserted msg 14 in buffer
buffer is... . 5 .. 2 .. 14 .
receiver removing msg 14 in buffer
buffer is... . 5 .. 2 .
sender has a msg: 7
sender inserted msg 7 in buffer
buffer is... . 5 .. 2 .. 7 .
sender has a msg: 13
sender inserted msg 13 in buffer
buffer is... . 5 .. 2 .. 7 .. 13 .
sender has a msg: 2
sender inserted msg 2 in buffer
buffer is... . 5 .. 2 .. 7 .. 13 .. 2 .
No comments:
Post a Comment