读写临界区的一个问题

_Wanderer2199 2021-04-13 02:49:39
我有一个循环链表,每个子线程只需要读链表结点里的数据,但主线程有时会对循环链表里的结点进行改写。
我的设计思路是每次主线程改写链表结点都需要进入临界区,改写完成离开。请教大佬们子线程读链表结点的数据可以不加临界区吗?如果需要加临界区,那么给每个子线程各分配一个循环链表是否效率会更高些?(好像需要用到TLS,那么主线程如何访问每个线程TLS里的循环链表呢)
...全文
2932 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
冰思雨 2021-04-22
  • 打赏
  • 举报
回复
首先,要想保证数据一致性,就必须要上锁。 其次,推荐对链表的读写访问,使用读写锁,比较容易上手实现。 再次,如果这个循环链表是自己编写代码实现的,可以在更改节点以及前后节点同时上锁,对于整个链表来讲,这是局部上锁,多线程高并发的时候,没有上锁的数据,可以直接进行读取,上锁的局部(1~3个节点)可以等更改完毕后再进行读写。
an_bachelor 2021-04-21
  • 打赏
  • 举报
回复
引用 10 楼 待续_1006 的回复:
[quote=引用 6 楼 tiger波波 的回复:]只有一个线程修改共享资源不需要加。其他线程只是读,不影响
但是问题如果此时正在更新数据,那读取到的数据岂不是脏数据了[/quote] 这个要从业务出发来带设计,而不是反过来, 从业务出发,许多场景(特别是面向普通人的互联网应用)是可以接受刚开始拿不到正确数据,重试一次或几次拿到正确数据的。。
待续_1006 2021-04-21
  • 打赏
  • 举报
回复
引用 6 楼 tiger波波 的回复:
只有一个线程修改共享资源不需要加。其他线程只是读,不影响
但是问题如果此时正在更新数据,那读取到的数据岂不是脏数据了
Eleven 2021-04-15
  • 打赏
  • 举报
回复
InitializeSRWLock/AcquireSRWLockExclusive AcquireSRWLockShared/ReleaseSRWLockShared SleepConditionVariableCS/SleepConditionVariableSRW/WakeConditionVariable/WakeAllConditionVariable
an_bachelor 2021-04-15
  • 打赏
  • 举报
回复
读写锁是可以的,其实工作中多数情况性能没有那么关键,你直接每个操作都加锁也未尝不可, 另外你可以直接扔数据库里头,这样你还可以灵活调整隔离级别,也许将来你还需要保留状态呢,这又方便了。
bluesen 2021-04-14
  • 打赏
  • 举报
回复
引用 1 楼 sevancheng 的回复:
加锁比较安全,但是效率不高,可以了解一下读写锁;
给每个子线程各分配一个循环链表,也涉及到数据同步问题,效率应该更差

读写锁是正解
tiger波波 2021-04-14
  • 打赏
  • 举报
回复
只有一个线程修改共享资源不需要加。其他线程只是读,不影响
_Wanderer2199 2021-04-13
  • 打赏
  • 举报
回复
引用 2 楼 tiger波波的回复:
修改数据的主线程只有一个吧?如果子线程不加那么主线程也没必要加,因为修改数据的主线程只有一个,没人跟它抢,就没有冲突。 你的循环链表的数据是公用的吗?如果是公用的,你给每个子线程都分配一个循环链表,那么主线程每次需要更新所有的子线程链表,每次都要跟所有的子线程竞争。一个链表的话是主线程、所有子线程之间竞争;多个链表是主线程和每一个子线程之间竞争,感觉效率高不到哪去。
再确认一下! 我的子线程是while(1)持续读取循环链表里的数据 主线程可能会对循环链表进行修改 不过只有主线程修改 不用加临界区吗
_Wanderer2199 2021-04-13
  • 打赏
  • 举报
回复
好的谢谢指点!
_Wanderer2199 2021-04-13
  • 打赏
  • 举报
回复
引用 2 楼 tiger波波的回复:
修改数据的主线程只有一个吧?如果子线程不加那么主线程也没必要加,因为修改数据的主线程只有一个,没人跟它抢,就没有冲突。 你的循环链表的数据是公用的吗?如果是公用的,你给每个子线程都分配一个循环链表,那么主线程每次需要更新所有的子线程链表,每次都要跟所有的子线程竞争。一个链表的话是主线程、所有子线程之间竞争;多个链表是主线程和每一个子线程之间竞争,感觉效率高不到哪去。
好的谢谢指点!
tiger波波 2021-04-13
  • 打赏
  • 举报
回复
修改数据的主线程只有一个吧?如果子线程不加那么主线程也没必要加,因为修改数据的主线程只有一个,没人跟它抢,就没有冲突。 你的循环链表的数据是公用的吗?如果是公用的,你给每个子线程都分配一个循环链表,那么主线程每次需要更新所有的子线程链表,每次都要跟所有的子线程竞争。一个链表的话是主线程、所有子线程之间竞争;多个链表是主线程和每一个子线程之间竞争,感觉效率高不到哪去。
sevancheng 2021-04-13
  • 打赏
  • 举报
回复
加锁比较安全,但是效率不高,可以了解一下读写锁;
给每个子线程各分配一个循环链表,也涉及到数据同步问题,效率应该更差
课程目标快速的掌握读写分离+分表的实战,即插即用适用人群IT从业人员,开发人员,Java从业者,互联网从业者,性能调优人群课程简介ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈。它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成,shardingSphere定位为关系型数据库中间件。Sharding-JDBCSharding-JDBC是Sharding-Sphere的第一个产品,也是Sharding-Sphere的前身,是当当网开源的一个产品。定位为轻量级的Java框架,在Java的JDBC层提供额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。他们均提供标准化的数据分片、读写分离、柔性事务和数据治理功能,可适用于如Java同构、异构语言、容器、云原生等各种多样化的应用场景。Sharding-JDBC可以通过Java,YAML,Spring命名空间和Spring Boot Starter四种方式配置,开发者可根据场景选择适合的配置方式。课程特色 本章节以尽量短的时间,为使用者提供最简单的ShardingSphere的快速入门。课程说明该课程属于系列课程,分为读写分离,分库不分表,不分库分表,分库分表,读写分离+分库分表共5个回合。本课程属于其中一个回合,请各位小哥哥们注意,课程的标题哦~

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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