ProdCons

ProdCons è un programma C il cui obiettivo è mostrare l’utilizzo di semplici servizi per la gestione di file.

 1#ifndef __PROD_CONS__
 2#define __PROD_CONS__
 3
 4#define SHARED_SIZE 4096
 5#define SHARED_NAME "prod_cons_shm"
 6#define LONG_SHARED_NAME "/dev/shm/"SHARED_NAME
 7#define MSG_SIZE 255
 8#define MSG_SIZE_RAW 256
 9#define log(...) do{printf("[%d]:", getpid()); printf(__VA_ARGS__);}while(0)
10
11#include <pthread.h>
12
13typedef struct __shared_data{
14    pthread_barrier_t barrier;
15    pthread_mutex_t mutex;
16    void *prod_base_addr;
17    pid_t prod_pid;
18    pid_t cons_pid;
19    char message[256];
20}shared_data_t;
21
22#endif
 1#include <sys/mman.h>
 2#include <sys/stat.h>        /* For mode constants */
 3#include <fcntl.h>           /* For O_* constants */
 4#include <unistd.h>          /* For truncate */
 5#include <stdio.h>           /* For printf */
 6#include <stdlib.h>          /* For exit */
 7
 8#include "prod_cons.h"
 9
10
11
12int main(int argc, char *argv[]){
13    shared_data_t *shared_data;
14    pthread_barrierattr_t pthread_barrierattr;
15    pthread_mutexattr_t   pthread_mutexattr;
16    int res;
17    pid_t pid = getpid();
18
19    int fd = shm_open(SHARED_NAME, O_CREAT | O_EXCL | O_RDWR, 0666);
20    if(fd == -1) {
21        log("The shared memory already exists...Probably there is another producer...exit\n");
22        goto fail_exit;
23    }
24
25    res = ftruncate(fd, SHARED_SIZE);
26    if(res == -1) {
27        log("I cannot allocate enough memory...exit\n");
28        goto abort;
29    }
30
31    shared_data = mmap(NULL, SHARED_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
32    if(shared_data == MAP_FAILED) {
33        log("I cannot map memory...exit\n");
34        goto abort;
35    }
36
37    close(fd);
38
39    pthread_barrierattr_setpshared(&pthread_barrierattr, PTHREAD_PROCESS_SHARED );
40    pthread_barrier_init(&shared_data->barrier, &pthread_barrierattr, 2);
41
42    pthread_mutexattr_settype(&pthread_mutexattr, PTHREAD_MUTEX_DEFAULT);
43    pthread_mutexattr_setpshared(&pthread_mutexattr,  PTHREAD_PROCESS_SHARED);
44    pthread_mutex_init(&shared_data->mutex, &pthread_mutexattr);
45
46    log("I'll WAIT for a process at %p\n", shared_data);
47    shared_data->prod_pid = pid;
48    shared_data->prod_base_addr = shared_data;
49    shared_data->message[MSG_SIZE] = '\0';
50    pthread_mutex_lock(&shared_data->mutex);
51    pthread_barrier_wait(&shared_data->barrier);
52    log("Process %d arrived\n", shared_data->cons_pid);
53
54
55    log("I'll produce data...\n");
56    sprintf(shared_data->message, "Nice to meet you");
57    log("Done\n");
58
59    pthread_mutex_unlock(&shared_data->mutex);
60
61    exit(0);
62
63abort:
64    shm_unlink(SHARED_NAME);
65    close(fd);
66fail_exit:
67    exit(1);
68
69
70}
 1#include <sys/mman.h>
 2#include <sys/stat.h>        /* For mode constants */
 3#include <fcntl.h>           /* For O_* constants */
 4#include <unistd.h>          /* For truncate */
 5#include <stdio.h>           /* For printf */
 6#include <stdlib.h>          /* For exit */
 7
 8#include "prod_cons.h"
 9
10
11
12int main(int argc, char *argv[]){
13    shared_data_t *shared_data;
14    pid_t pid = getpid();
15
16
17    int fd = shm_open(SHARED_NAME, O_RDWR, 0666);
18    if(fd == -1) {log("shared mem not initialized\n");exit(1);}
19    shared_data = mmap(NULL, SHARED_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
20
21    if(shared_data == MAP_FAILED) {
22        log("I cannot map memory...exit\n");
23        close(fd);
24        exit(1);
25    }
26
27    log("shared_data cons address %p\n", shared_data);
28    log("shared_data prod address %p\n", shared_data->prod_base_addr);
29    close(fd);
30
31    log("I'll JOIN for a process at %p\n", shared_data);
32    shared_data->cons_pid = pid;
33    pthread_barrier_wait(&shared_data->barrier);
34    log("Joined. prod pid %d:\n", shared_data->prod_pid);
35
36    pthread_mutex_lock(&shared_data->mutex);
37    log("I'll consume data...\n");
38    log("Message: '%s'\n", shared_data->message);
39    log("Done\n");
40
41    pthread_mutex_unlock(&shared_data->mutex);
42
43    shm_unlink(SHARED_NAME);
44}

Riferimenti