多进程测试共享内存原子变量
目录
#include <atomic>
#include <fcntl.h> /* For O_* constants */
#include <fstream>
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h> /* For mode constants */
#include <sys/wait.h>
#include <thread>
#include <unistd.h>/* For fork*/
#include <vector>
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define SVSHM_MODE (SHM_R | SHM_W | SHM_R >> 3 | SHM_R >> 6)
std::atomic<int> acnt = ATOMIC_VAR_INIT(0);
int cnt;
void fun() {
for (int n = 0; n < 1000; ++n) {
std::atomic_fetch_add(&acnt, 1); // 原子的
++cnt; // 未定义行为,实际上会失去一些更新
}
return;
}
int main(void) {
std::vector<std::thread> v;
for (int n = 0; n < 10; ++n) {
v.emplace_back(fun);
}
for (auto &t : v) {
t.join();
}
printf("The atomic counter is %u\n", acnt.load());
printf("The non-atomic counter is %u\n", cnt);
int shmid =
shmget(IPC_PRIVATE, sizeof(std::atomic<int>), SVSHM_MODE | IPC_CREAT);
std::atomic<int> *pAtomic = (std::atomic<int> *)shmat(shmid, NULL, 0);
std::cout << "share addr:" << pAtomic << std::endl;
std::vector<pid_t> pidList;
int processId = 0;
int thNum = 3;
std::ofstream test_case_ofs;
for (; processId < thNum; processId++) {
pid_t pid = fork();
if (pid == 0 || pid == -1) {
// pAtomic = (std::atomic<int> *)shmat(shmid, NULL, 0); /*not must*/
std::cout << "share addr:" << pAtomic << std::endl;
std::string file = "group" + std::to_string(processId);
test_case_ofs.open(file);
break;
} else {
pidList.push_back(pid);
}
}
if (processId < thNum) {
int test_index;
while (test_index = std::atomic_fetch_add(pAtomic, 1), test_index < 1000) {
test_case_ofs << "index:" << test_index << std::endl;
}
} else {
int wstatus = 0;
for (auto &cpid : pidList) {
waitpid(cpid, &wstatus, 0);
}
shmctl(shmid, IPC_RMID, NULL);//delete id
std::cout << "The share mem atomic counter is " << pAtomic->load() << std::endl;
}
}