多进程的共享内存中使用互斥量同步数据

功能:父子进程在共享内存中互斥累加数据(counter)。


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

struct mutex_package_t {
    pthread_mutex_t lock;
    pthread_mutexattr_t lock_attr;
    int shm_id;
    int counter;
};

const int create_shm_id(const int index, const size_t size)
{
    const int shm_id = shmget((key_t)index, size, 0666 | IPC_CREAT);
    // const int shm_id = shmget(IPC_PRIVATE, size, (SHM_R | SHM_W | IPC_CREAT));
    return shm_id;
}

const int init_mutex(void *addr)
{
    mutex_package_t *mp = (mutex_package_t *)addr;
    
    pthread_mutexattr_init(&(mp->lock_attr));
    pthread_mutexattr_setpshared(&(mp->lock_attr), PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&(mp->lock), &(mp->lock_attr));
    return 0;
}

mutex_package_t *create_mutex_package(const int index)
{
    const int shm_id = create_shm_id(index, sizeof(mutex_package_t));
    mutex_package_t *mp = (mutex_package_t *)shmat(shm_id, NULL, SHM_R | SHM_W);
    // mutex_package_t *mp = (mutex_package_t *)shmat(shm_id, NULL, 0);
    memset(mp, 0, sizeof(*mp));

    init_mutex(mp);
    mp->shm_id = shm_id;
}

const int destory_mutex_package(mutex_package_t *mp)
{
    pthread_mutex_destroy(&(mp->lock));
    pthread_mutexattr_destroy(&(mp->lock_attr));
    shmctl(mp->shm_id, IPC_RMID, NULL);
    return 0;
}

int main(int argc, char *argv[])
{
    mutex_package_t *mp = create_mutex_package(111);
    int *counter = &(mp->counter);
    pid_t pid = 0;
    int i = 0;
    const int N = 10;
    pid_t exit_pid = 0;
    int status = 0;

    pid = fork();
    if (pid > 0) {
        /* master start to count */
        for (i = 0; i < N; ++i) {
            pthread_mutex_lock(&(mp->lock));
            *counter = *counter + 1;
            std::cout << "master pid: " << getpid() 
                      << ", &counter: " << std::hex << counter 
                      << ", counter:  " << std::dec << *counter << std::endl;
            pthread_mutex_unlock(&(mp->lock));
            sleep(1);
        }
        std::cout << "master: finish count" << std::endl;
        
        /* wait worker process */
        while (true) {
            exit_pid = waitpid(-1, &status, WNOHANG);
            if (exit_pid == pid) {
                std::cout << "worker[" << exit_pid << "] process exit, status: " << status << std::endl; 
                break;
            } else {
                std::cout << "process[" << exit_pid << "] exit, status: " << status << std::endl;
                sleep(1); 
            }
        }
        std::cout << "master: start to destory" << std::endl;
        destory_mutex_package(mp);
    } else if (pid == 0) {
        /* worker start to count */
        for (i = 0; i < N; ++i) {
            pthread_mutex_lock(&(mp->lock));
            *counter = *counter + 2;
            std::cout << "worker pid: " << getpid() 
                      << ", &counter: " << std::hex << counter 
                      << ", counter:  " << std::dec << *counter << std::endl;
            pthread_mutex_unlock(&(mp->lock));
            sleep(1);
        }
        std::cout << "worker: finish count" << std::endl;
        sleep(4);
    } else {
        std::cout << "Failed to fork" << std::endl;
        exit(EXIT_FAILURE);
    }

    return 0;
}

编译:

g++ ./multi_process_shm_mutex.cpp -std=c++11 -pthread

运行:

$ ./a.out 
master pid: 2972, &counter: 0x7fe032ac3030, counter:  1
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  3
master pid: 2972, &counter: 0x7fe032ac3030, counter:  4
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  6
master pid: 2972, &counter: 0x7fe032ac3030, counter:  7
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  9
master pid: 2972, &counter: 0x7fe032ac3030, counter:  10
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  12
master pid: 2972, &counter: 0x7fe032ac3030, counter:  13
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  15
master pid: 2972, &counter: 0x7fe032ac3030, counter:  16
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  18
master pid: 2972, &counter: 0x7fe032ac3030, counter:  19
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  21
master pid: 2972, &counter: 0x7fe032ac3030, counter:  22
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  24
master pid: 2972, &counter: 0x7fe032ac3030, counter:  25
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  27
master pid: 2972, &counter: 0x7fe032ac3030, counter:  28
worker pid: 2974, &counter: 0x7fe032ac3030, counter:  30
master: finish counter
process[0] exit, status: 0
worker: finish counter
process[0] exit, status: 0
process[0] exit, status: 0
process[0] exit, status: 0
process[0] exit, status: 0
worker[2974] process exit, status: 0
master: start to destory

你可能感兴趣的:(LINUX,linux,多进程,共享内存)