freeeyes 发表于 2015-1-29 14:11:34

共享内存的多进程数据共享的一致性解决

最近终于有点有时间,在自己的任务日志中添加了一项
"研究多进程下共享内存数据的一致性"
经过两天的研究,写出了测试代码,并且测试通过。
很棒,解决了困扰我我好几年的一个疑惑。
不考虑windows了,Linux是我的主要开发环境。
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>

//add by freeeyes
//此测试代码,解决的是在多进程下,共享内存的安全性。
//测试用例是,一个进程创建10个线程,每个线程写100000次。
//再开两个进程,模拟多子进程写入,创造竞争机会
//思路,在共享内存中,记录一个pthread_mutex_t对象
//对这个线程锁对象添加属性,PTHREAD_PROCESS_SHARED
//效果不错 ^^

#define PERMS_IPC 0600

//测试类
struct _TestData
{
        pthread_mutex_t m_lock;
        int m_Data;
       
        _TestData()
        {
                m_Data = 0;
        }
};

//测试共享内存下线程锁的作用
char * CreatShm(key_t shmkey, int length)
{
        int        shmid;
        char *shmp;

        if((shmid = shmget(shmkey, length, PERMS_IPC|IPC_CREAT)) < 0)
        {
                return NULL;
        }

        if((shmp = (char *)shmat(shmid, (char *)0, 0)) == (char *) -1)
        {
                return NULL;
        }

        return shmp;
}

void * threadFunc(void *arg)
{
   _TestData* pTestData = (_TestData* )arg;
   
   for(int i = 0; i < 100000; i++)
   {
                   //这里添加对测试数据的锁判定
                   pthread_mutex_lock(&pTestData->m_lock);
                   pTestData->m_Data++;
                   //usleep(1);
                   pthread_mutex_unlock(&pTestData->m_lock);
   }
   
   return ((void *)0);
}

int main()
{
        char* pData = CreatShm(10031, sizeof(_TestData));
        if(NULL == pData)
        {
                printf("Create shm fail.\n");
        }
        else
        {
                /* 关键在这里 */
                pthread_mutexattr_t mattr;   
                pthread_mutexattr_init(&mattr);   
                pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);          
               
                pthread_mutex_t lock;       
                pthread_mutex_init(&lock, &mattr);
               
                _TestData* pTestData = (_TestData* )pData;
               
                pTestData->m_lock = lock;
                pTestData->m_Data = 0;
               
                //创建两个子进程,模拟多进程间的数据写同步
                for(int k = 0; k < 2; k++)
                {
                        //多进程
                        pid_t pid = fork();
               
                        //子进程
                        if(pid == 0)
                        {
                                //开始测试多线程
                                pthread_t nThreadID;
                                for(int i = 0; i < 10; i++)
                                {
                                        pthread_create(&nThreadID, NULL, threadFunc, (void*)pTestData);
                                }
                       
                                for(int i = 0; i < 10; i++)
                                {
                                        pthread_join(nThreadID, NULL);
                                }
                       
                                printf("Data=%d.\n", pTestData->m_Data);
                               
                                return 0;
                        }
                        printf("loop end.\n");
                }
               
                printf("father ok.\n");
        }
       
        return 0;
}

此代码在Linux下测试通过。
$ g++ -Wall -g -rdynamic -ldl -lpthread main.cpp -o test
$ ./test
loop end.
loop end.
father ok.
Data=1992233.
Data=2000000.

页: [1]
查看完整版本: 共享内存的多进程数据共享的一致性解决