求教一个多线程加锁的问题

狼异族 2020-10-19 07:37:13
多线程程序,其中一个1个线程用于定时初始化数据,另外多个线程访问初始化好的数据,我想在初始化的时候,其他线程不能访问程序,但是数据初始化完成之后,其它线程访问数据时能不加锁,因为加锁会导致访问线程之间互斥,这种该怎么设计?另外访问线程一致开启,无法停掉
...全文
493 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 12 楼 狼异族 的回复:
我现在的想法是增加一个原子变量,进入访问时变量+1,退出时-1,在初始化之前判等待变量=0,然后才开始初始化,但是不太确定这个方法是否可靠


这个方法的问题是,如果开始初始化,但还没有初始化完成,就有线程访问了,就会有问题。

引用 12 楼 狼异族 的回复:
[quote=引用 11 楼 zjq9931 的回复:]
这样的方式和加锁基本差不多了。
如果怕重置数据时,其他线程访问数据,可以设置一个值,其他线程访问数据前先检测值。如果是1,循环等待(时长自己定),如果是0,正常访问。
这个没法确定初始化的时候是否已经有线程在访问数据了[/quote]
初始化之前,发信号了。如果已经有线程在访问,就继续访问。下一轮访问的时候,检测到标记正在初始化,那就等待了。
问题是访问数据时间的长短。如果访问数据的时间比较长,那么就会有问题。如果时间比较短,就没有问题。

可以两种方法结合,就好了。
狼异族 2020-10-22
  • 打赏
  • 举报
回复
引用 11 楼 zjq9931 的回复:
这样的方式和加锁基本差不多了。 如果怕重置数据时,其他线程访问数据,可以设置一个值,其他线程访问数据前先检测值。如果是1,循环等待(时长自己定),如果是0,正常访问。
这个没法确定初始化的时候是否已经有线程在访问数据了
狼异族 2020-10-21
  • 打赏
  • 举报
回复
引用 8 楼 _mervyn 的回复:
你的初始化是什么意思。。。不是只初始化一次的意思吗? 你是指你的数据会多次被重置吗?
我现在的想法是增加一个原子变量,进入访问时变量+1,退出时-1,在初始化之前判等待变量=0,然后才开始初始化,但是不太确定这个方法是否可靠
狼异族 2020-10-21
  • 打赏
  • 举报
回复
对的,数据会被定时重置
  • 打赏
  • 举报
回复
引用 10 楼 狼异族 的回复:
[quote=引用 8 楼 _mervyn 的回复:]
你的初始化是什么意思。。。不是只初始化一次的意思吗?
你是指你的数据会多次被重置吗?
我现在的想法是增加一个原子变量,进入访问时变量+1,退出时-1,在初始化之前判等待变量=0,然后才开始初始化,但是不太确定这个方法是否可靠[/quote]
这样的方式和加锁基本差不多了。
如果怕重置数据时,其他线程访问数据,可以设置一个值,其他线程访问数据前先检测值。如果是1,循环等待(时长自己定),如果是0,正常访问。
_mervyn 2020-10-20
  • 打赏
  • 举报
回复
最好是 初始化完毕后 再启动访问线程 如果访问线程的启动不受你控制,无法办到这点的话, 那可以考虑这样:

std::atomic<bool> ready(false);
//初始化线程:
//做一系列初始化操作...
//...
//...
ready = true;

//访问线程:
while (!ready) { std::this_thread::yield(); } // 等待 ready 变为 true.
//之后才开始访问
//...
赵4老师 2020-10-20
  • 打赏
  • 举报
回复
使用AB双缓冲策略。 初始化A,访问B 初始化B,访问A
  • 打赏
  • 举报
回复
引用 2 楼 狼异族 的回复:
[quote=引用 1 楼 zjq9931 的回复:]初始化加锁,是没问题的。
但是多线程同时访问不能加锁?确定全是只读访问吧?全是只读访问是可以不加锁的。
确定是只读访问,如果不加锁,就没法和初始化线程区分开[/quote]

顺序执行啊,初始化执行完成后,再启动其他只读线程。
狼异族 2020-10-20
  • 打赏
  • 举报
回复
引用 1 楼 zjq9931 的回复:
初始化加锁,是没问题的。 但是多线程同时访问不能加锁?确定全是只读访问吧?全是只读访问是可以不加锁的。
确定是只读访问,如果不加锁,就没法和初始化线程区分开
_mervyn 2020-10-20
  • 打赏
  • 举报
回复
引用 7 楼 狼异族 的回复:
这个存在一个问题,访问线程在访问的过程中,初始化线程去初始化数据了,这个风险还是存在
你的初始化是什么意思。。。不是只初始化一次的意思吗? 你是指你的数据会多次被重置吗?
狼异族 2020-10-20
  • 打赏
  • 举报
回复
引用 5 楼 _mervyn 的回复:
最好是 初始化完毕后 再启动访问线程 如果访问线程的启动不受你控制,无法办到这点的话, 那可以考虑这样:

std::atomic<bool> ready(false);
//初始化线程:
//做一系列初始化操作...
//...
//...
ready = true;

//访问线程:
while (!ready) { std::this_thread::yield(); } // 等待 ready 变为 true.
//之后才开始访问
//...
这个存在一个问题,访问线程在访问的过程中,初始化线程去初始化数据了,这个风险还是存在
ztenv 版主 2020-10-20
  • 打赏
  • 举报
回复
说两种常用的: 1、读写锁 2、通知机制(条件变量,条件满足的时候通知)
  • 打赏
  • 举报
回复
初始化加锁,是没问题的。
但是多线程同时访问不能加锁?确定全是只读访问吧?全是只读访问是可以不加锁的。

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧