|
最近终于有点有时间,在自己的任务日志中添加了一项
"研究多进程下共享内存数据的一致性"
经过两天的研究,写出了测试代码,并且测试通过。
很棒,解决了困扰我我好几年的一个疑惑。
不考虑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("[Main]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[10];
- for(int i = 0; i < 10; i++)
- {
- pthread_create(&nThreadID[i], NULL, threadFunc, (void*)pTestData);
- }
-
- for(int i = 0; i < 10; i++)
- {
- pthread_join(nThreadID[i], NULL);
- }
-
- printf("[main]Data=%d.\n", pTestData->m_Data);
-
- return 0;
- }
- printf("[main]loop end.\n");
- }
-
- printf("[main]father ok.\n");
- }
-
- return 0;
- }
复制代码 此代码在Linux下测试通过。
[m2mjk@nbc testlock]$ g++ -Wall -g -rdynamic -ldl -lpthread main.cpp -o test
[m2mjk@nbc testlock]$ ./test
[main]loop end.
[main]loop end.
[main]father ok.
[main]Data=1992233.
[main]Data=2000000.
|
|