功能:父子进程在共享内存中互斥累加数据(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