今天我们来聊聊同步,假设一种场景,就是在客户端Activity中,开启多个线程同时写入mmap内存中,看看会怎样
- private fun testMultiThreadWriteMMIPC() {
- "set data".print(getProcessName())
- val countDownLatch = CountDownLatch(2)
- Thread {
- var index = 10000
- //重复写入一万次
- repeat(10000) {
- index++
- MMIPC.setData(index.toString(), index.toString())
- }
- countDownLatch.countDown()
- }.start()
- Thread {
- var index = 20000
- //重复写入一万次
- repeat(10000) {
- index++
- MMIPC.setData(index.toString(), index.toString())
- }
- countDownLatch.countDown()
- }.start()
- //等待两个线程结束
- countDownLatch.await()
- //打印写入数据的长度
- MMIPC.getData("").length.toString().print(getProcessName())
- }
- 2022-07-20 22:20:46.743 9933-9933/com.zzy.mmipc D/MMIPC->: 进程:com.zzy.mmipc 日志: init
- 2022-07-20 22:20:46.744 9933-9933/com.zzy.mmipc D/MMIPC->: open file /data/user/0/com.zzy.mmipc/files
- 2022-07-20 22:20:46.744 9933-9933/com.zzy.mmipc E/MMIPC->: pid[9933]
- 2022-07-20 22:20:46.744 9933-9933/com.zzy.mmipc D/MMIPC->: open m_fd[78], /data/user/0/com.zzy.mmipc/files/default_mmap.ipc
- 2022-07-20 22:20:46.744 9933-9933/com.zzy.mmipc D/MMIPC->: m_fd size[0]
- 2022-07-20 22:20:46.744 9933-9933/com.zzy.mmipc D/MMIPC->: getFileSize m_file_size 0, default_mmap_size 4161536
- 2022-07-20 22:20:46.744 9933-9933/com.zzy.mmipc D/MMIPC->: mmap success
- 2022-07-20 22:20:46.845 9933-9933/com.zzy.mmipc D/MMIPC->: 进程:com.zzy.mmipc 日志: set data
- 2022-07-20 22:20:46.913 9933-9933/com.zzy.mmipc D/MMIPC->: 进程:com.zzy.mmipc 日志: 237004
正常长度等于20000*12 = 240000,因为setData,我会将key和value进行预处理变成如下,所以一次setData的长度是12,那么重试两万次就是 24万
string content = key + ":" + value + ",";
有什么办法可以解决该问题呢,往下看
利用Looper机制,实现单线程中让所有的任务按顺序执行,直接代码验证效果,创建一个dev-looper分支,然后代码改变如下

然后测试结果如下,这次是240000
- 2022-07-20 22:43:47.874 11336-11336/com.zzy.mmipc D/MMIPC->: 进程:com.zzy.mmipc 日志: init
- 2022-07-20 22:43:47.897 11336-11336/com.zzy.mmipc D/MMIPC->: open file /data/user/0/com.zzy.mmipc/files
- 2022-07-20 22:43:47.897 11336-11336/com.zzy.mmipc E/MMIPC->: pid[11336]
- 2022-07-20 22:43:47.897 11336-11336/com.zzy.mmipc D/MMIPC->: open m_fd[76], /data/user/0/com.zzy.mmipc/files/default_mmap.ipc
- 2022-07-20 22:43:47.897 11336-11336/com.zzy.mmipc D/MMIPC->: m_fd size[0]
- 2022-07-20 22:43:47.897 11336-11336/com.zzy.mmipc D/MMIPC->: getFileSize m_file_size 0, default_mmap_size 4161536
- 2022-07-20 22:43:47.897 11336-11336/com.zzy.mmipc D/MMIPC->: mmap success
- 2022-07-20 22:43:48.265 11336-11336/com.zzy.mmipc D/MMIPC->: 进程:com.zzy.mmipc 日志: set data
- 2022-07-20 22:43:56.241 11336-11336/com.zzy.mmipc D/MMIPC->: 进程:com.zzy.mmipc 日志: 240000
我们想想,这样实现有什么问题,功能没什么问题,但失去了原本用C++实现的好处,那就是跨平台能力,如果再IOS端,我们如何实现呢?接下来我们考虑用C++的方式实现对多线程写入
C/C++Linux服务器开发高级架构师/C++后台开发架构师免费学习地址
【文章福利】另外还整理一些C++后台开发架构师 相关学习资料,面试题,教学视频,以及学习路线图,免费分享有需要的可以自行添加:Q群:720209036 点击加入~ 群文件共享

该锁限制同一时间只有一个线程访问数据,实现如下,下面跨进程的时候在详细了解mutex
- //声明
- pthread_mutex_t m_lock;
- //setData函数中使用
- void MMIPC::setData(const string &key, const string &value) {
- //加锁
- pthread_mutex_lock(&m_lock);
- string content = key + ":" + value + ",";
- // ALOGD("setData content=%s", content.c_str());
- size_t numberOfBytes = content.length();
- if (m_position + numberOfBytes > m_file_size) {
- auto msg = "m_position: " + to_string(m_position) + ", numberOfBytes: " +
- to_string(numberOfBytes) +
- ", m_file_size: " + to_string(m_file_size);
- throw out_of_range(msg);
- }
- m_position = strlen(m_ptr);
- memcpy(m_ptr + m_position, (void *) content.c_str(), numberOfBytes);
- // ALOGD("setData success m_ptr.len=%d", m_position + numberOfBytes);
- //释放锁
- pthread_mutex_unlock(&m_lock);
- }
- 2022-07-20 23:04:10.958 12322-12322/com.zzy.mmipc D/MMIPC->: 进程:com.zzy.mmipc 日志: init
- 2022-07-20 23:04:10.959 12322-12322/com.zzy.mmipc D/MMIPC->: open file /data/user/0/com.zzy.mmipc/files
- 2022-07-20 23:04:10.959 12322-12322/com.zzy.mmipc E/MMIPC->: pid[12322]
- 2022-07-20 23:04:10.959 12322-12322/com.zzy.mmipc D/MMIPC->: open m_fd[78], /data/user/0/com.zzy.mmipc/files/default_mmap.ipc
- 2022-07-20 23:04:10.959 12322-12322/com.zzy.mmipc D/MMIPC->: m_fd size[0]
- 2022-07-20 23:04:10.959 12322-12322/com.zzy.mmipc D/MMIPC->: getFileSize m_file_size 0, default_mmap_size 4161536
- 2022-07-20 23:04:10.959 1