2016-09-18 3 views
0

Проблема в том, что я хочу, чтобы наш объект был равным 93. Я хочу, чтобы переменная была разделена всеми потоками. Как статическая переменная, общая для всех объектов, я хочу, чтобы переменная была общей для всех потоков.Как использовать Mmap для обмена памятью. Пожалуйста, исправьте мой код

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 

static int *glob_var; 

int main(void) 
    { 
    glob_var = (int*)mmap(NULL, sizeof *glob_var, PROT_READ | PROT_WRITE, 
       MAP_SHARED | MAP_ANONYMOUS, -1, 0); 

    *glob_var = 1; 
    int ppid =fork(); 

    if (ppid == 0) { 
    *glob_var = 92; printf("%d\n", *glob_var); 

    } else if(ppid!=0){ 
    (*glob_var)++; /////I want a 93 over here??? 
     printf("%d\n", *glob_var); /////I want a 93 over here??? print 
     munmap(glob_var, sizeof *glob_var); 
    } 
    return 0; 
    } 
+0

переменные являются общими для всех потоков. Вам не нужно ничего делать, чтобы это произошло. – xaxxon

+0

В этом разница между потоками и процессами. Каждый процесс имеет свою собственную память, все потоки выполняются в одной и той же памяти. Просто используйте глобальные переменные или указатели прохода между потоками. – Barmar

ответ

0

Оба процесса обновления glob_var. Вам необходимо координировать доступ к этой общей памяти. Требуется гарантировать правильный порядок модификации данных, то есть должно быть назначено значение 92.

Semaphore часто используется для синхронизации операций в таких ситуациях:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 
#include <unistd.h> 

// Binary semaphore implementation. Initial state 0 
union semun 
{ 
    int val; 
    struct semid_ds *buf; 
    unsigned short int *array; 
    struct seminfo *__buf; 
}; 

int binary_semaphore_allocation (key_t key, int sem_flags) 
{ 
    return semget (key, 1, sem_flags); 
} 

int binary_semaphore_deallocate (int semid) 
{ 
    union semun ignored_argument; 
    return semctl (semid, 1, IPC_RMID, ignored_argument); 
} 

int binary_semaphore_initialize (int semid) 
{ 
    union semun argument; 
    unsigned short values[1]; 
    values[0] = 0; 
    argument.array = values; 
    return semctl (semid, 0, SETALL, argument); 
} 

int binary_semaphore_wait (int semid) 
{ 
    struct sembuf operations[1]; 
    operations[0].sem_num = 0; 
    /* Decrement by 1. */ 
    operations[0].sem_op = -1; 
    operations[0].sem_flg = SEM_UNDO; 
    return semop (semid, operations, 1); 
} 

int binary_semaphore_post (int semid) 
{ 
    struct sembuf operations[1]; 
    operations[0].sem_num = 0; 
    /* Increment by 1. */ 
    operations[0].sem_op = 1; 
    operations[0].sem_flg = SEM_UNDO; 
    return semop (semid, operations, 1); 
} 

int main(void) 
{ 
    key_t ipc_key; 
    ipc_key = ftok(".", 'S'); 
    int sem_id; 

    glob_var = (int*)mmap(NULL, sizeof *glob_var, PROT_READ | PROT_WRITE, 
       MAP_SHARED | MAP_ANONYMOUS, -1, 0); 

    *glob_var = 1; 

    if ((sem_id=binary_semaphore_allocation(ipc_key, IPC_CREAT|IPC_EXCL)) != -1) 
    { 
    if (binary_semaphore_initialize(sem_id) == -1) 
    { 
     printf("Semaphore initialization failed"); 
     return 2; 
    } 
    } 

    int ppid = fork(); 
    if (ppid == 0) 
    { 
    if ((sem_id = binary_semaphore_allocation(ipc_key, 0)) == -1) 
    { 
     printf("Child process failed to open semaphore"); 
     return 3; 
    } 
    } 
    else 
    { 
    // Wait in parent process until child update glob_var 
    binary_semaphore_wait(sem_id); 
    } 

    if (ppid == 0) 
    { 
    *glob_var = 92; 
    printf("%d\n", *glob_var); 
    binary_semaphore_post(sem_id); 
    } 
    else if(ppid!=0) 
    { 
    (*glob_var)++; 
    printf("%d\n", *glob_var); 
    munmap(glob_var, sizeof *glob_var); 
    binary_semaphore_deallocate(sem_id); 
    } 

    return 0; 
} 

Выход:

92 
93