多进程测试共享内存原子变量

目录

    #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;
      }
    }
    
    

    posted on 2020-10-30 16:13  ims-  阅读(397)  评论(0编辑  收藏  举报

    导航