多线程如何对数组下标同步

OneOnce 2020-10-11 10:23:24
例如创建了N(如10个线程)个线程和一个大小为5的数组。 场景: A线程写下标为0的数组项,B和C线程同时写下标为1的数组项 问题: 如何使得A线程写下标0时,不影响B和C线程写下标1,但B和C之间是互斥的。也就说如果使用锁,如何做到只锁定数组某一项? PS: 第一个提供可用demo加200分
...全文
1045 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
StevenV6 2020-10-19
  • 打赏
  • 举报
回复
对数组的操作放到一个线程1,其他通过消息队列给线程1,让线程1来操作数组的读写,这样就不存在竞争了
OneOnce 2020-10-17
  • 打赏
  • 举报
回复
手机端结不了贴,回去结贴,大概思路是用CAS
OneOnce 2020-10-13
  • 打赏
  • 举报
回复
引用 25 楼 丁劲犇的回复:
主要是B,C在读写时,会不会访问到A的值?这些维度之间不是独立的吧!如果是独立的,就不用这么麻烦了。
实际上任何一个线程都会访问任意数组下标,可能是读,也可能是写
  • 打赏
  • 举报
回复
主要是B,C在读写时,会不会访问到A的值?这些维度之间不是独立的吧!如果是独立的,就不用这么麻烦了。
OneOnce 2020-10-13
  • 打赏
  • 举报
回复
引用 22 楼 zjq9931的回复:
[quote=引用 21 楼 OneOnce 的回复:][quote=引用 18 楼 赵4老师的回复:]
#include <pthread.h>
pthread_mutex_t mutexes[5];
int data[5];
void* handle(void* arg){
while(1){
for (int i=0;i<5;i++) {
pthread_mutex_lock(&mutexes[i]);
data[i]=i;
pthread_mutex_unlock(&mutexes[i]);
}
}
}
int main() {
int i;
for(i=0;i<10;++i) pthread_mutex_init(&mutexes[i],NULL);
pthread_t p[10];
for(i=0;i<10;++i) pthread_create(&p[i],NULL,handle,NULL);
for(i=0;i<10;++i) pthread_join(p[i],NULL);
return 0;
}


这个就是数组有多大,锁就多少。是实现了,但是实际中数组可能很大[/quote]

如果是基本类型可以使用interlocked系列函数操作。就好了,不用专门上锁。[/quote] 😊复杂类型
赵4老师 2020-10-13
  • 打赏
  • 举报
回复
Do not let me think.
  • 打赏
  • 举报
回复
引用 21 楼 OneOnce 的回复:
[quote=引用 18 楼 赵4老师的回复:]
#include <pthread.h>
pthread_mutex_t mutexes[5];
int data[5];
void* handle(void* arg){
while(1){
for (int i=0;i<5;i++) {
pthread_mutex_lock(&mutexes[i]);
data[i]=i;
pthread_mutex_unlock(&mutexes[i]);
}
}
}
int main() {
int i;
for(i=0;i<10;++i) pthread_mutex_init(&mutexes[i],NULL);
pthread_t p[10];
for(i=0;i<10;++i) pthread_create(&p[i],NULL,handle,NULL);
for(i=0;i<10;++i) pthread_join(p[i],NULL);
return 0;
}


这个就是数组有多大,锁就多少。是实现了,但是实际中数组可能很大[/quote]

如果是基本类型可以使用interlocked系列函数操作。就好了,不用专门上锁。
  • 打赏
  • 举报
回复
楼主这个需求只需要原子写即可
  • 打赏
  • 举报
回复
[quote=引用 24 楼 OneOnce 的回复复杂类型[/quote]

自定义类型吗?如果自定义的,那就让数据类型自锁。每个元素都自锁。
如果不是自定义类型,那就需要自己维护锁了。
  • 打赏
  • 举报
回复
这是要做ldpc的并行纠错之类的算法吗? 如果你的需求,可以人为给线程规定好做的区域,比如用行列的范围同余线程数N,分配任务。 还有,就是做一个镜像数组,首先多线程是读1写2,而后等大家都走完一波,再读2写1,如此迭代,不需要锁也。
lin5161678 2020-10-12
  • 打赏
  • 举报
回复
和下标一一样加锁
OneOnce 2020-10-12
  • 打赏
  • 举报
回复
引用 4 楼 lin5161678的回复:
下标0 没线程竞争不用管 A线程写下标0时本来就不影响B和C线程写下标1
可能有X或Y线程也要访问下标0,如果A锁住了arr[0],这时候就影响了其他线程访问arr其他下标
千梦一生 2020-10-12
  • 打赏
  • 举报
回复
引用 3 楼 OneOnce 的回复:
[quote=引用 1 楼 千梦一生的回复:]我感觉仅A单独写[0]内存不存在对该内存的竞争啊。

不过大多数情况有读就有写。这时候就要考虑互斥的问题了。

int arr[10]
---------------------------------------------------
线程B:
...
lock(第二个元素的读写锁)
写arr[1]
unlock
...
---------------------------------------------------
线程C:
...
lock(第二个元素的读写锁)
写arr[1]
unlock
...
---------------------------------------------------

这样会锁住整个arr[/quote]

我记忆中lock是锁代码的?我感觉应该没记错啊。只锁住了两个针对arr[1]的写操作无法并行。
lin5161678 2020-10-12
  • 打赏
  • 举报
回复
下标0 没线程竞争不用管 A线程写下标0时本来就不影响B和C线程写下标1
OneOnce 2020-10-12
  • 打赏
  • 举报
回复
引用 1 楼 千梦一生的回复:
我感觉仅A单独写[0]内存不存在对该内存的竞争啊。

不过大多数情况有读就有写。这时候就要考虑互斥的问题了。

int arr[10]
---------------------------------------------------
线程B:
...
lock(第二个元素的读写锁)
写arr[1]
unlock
...
---------------------------------------------------
线程C:
...
lock(第二个元素的读写锁)
写arr[1]
unlock
...
---------------------------------------------------
这样会锁住整个arr
赵4老师 2020-10-12
  • 打赏
  • 举报
回复
弄一个大小为5的锁数组。
千梦一生 2020-10-12
  • 打赏
  • 举报
回复
我感觉仅A单独写[0]内存不存在对该内存的竞争啊。

不过大多数情况有读就有写。这时候就要考虑互斥的问题了。

int arr[10]
---------------------------------------------------
线程B:
...
lock(第二个元素的读写锁)
写arr[1]
unlock
...
---------------------------------------------------
线程C:
...
lock(第二个元素的读写锁)
写arr[1]
unlock
...
---------------------------------------------------
OneOnce 2020-10-12
  • 打赏
  • 举报
回复
引用 18 楼 赵4老师的回复:
#include <pthread.h>
pthread_mutex_t mutexes[5];
int data[5];
void* handle(void* arg){
    while(1){
        for (int i=0;i<5;i++) {
            pthread_mutex_lock(&mutexes[i]);
            data[i]=i;
            pthread_mutex_unlock(&mutexes[i]);
        }
    }
}
int main() {
    int i;
    for(i=0;i<10;++i) pthread_mutex_init(&mutexes[i],NULL);
    pthread_t p[10];
    for(i=0;i<10;++i) pthread_create(&p[i],NULL,handle,NULL);
    for(i=0;i<10;++i) pthread_join(p[i],NULL);
    return 0;
}

这个就是数组有多大,锁就多少。是实现了,但是实际中数组可能很大
OneOnce 2020-10-12
  • 打赏
  • 举报
回复
这个不行,线程x先来拿到数据,线程y后来也拿到数据,刚好x线程休眠/挂起/时间片到,结果y线程先执行完
OneOnce 2020-10-12
  • 打赏
  • 举报
回复
现在数组小可能还行,假如数组很大就要配数组大小一样多的锁
加载更多回复(11)

64,282

社区成员

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

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