当前位置: 技术问答>linux和unix
高手请进:多线程访问同一链表,需不需要加锁?
来源: 互联网 发布时间:2015-09-24
本文导语: 多线程访问同一链表(准确的说应是stl的map): 1.只是读操作,并且不会同时访问同一个元素。 2.没有删除操作,有添加。 考虑到多线程的效率,我不想加锁,请教高手,会不会出问题? ...
多线程访问同一链表(准确的说应是stl的map):
1.只是读操作,并且不会同时访问同一个元素。
2.没有删除操作,有添加。
考虑到多线程的效率,我不想加锁,请教高手,会不会出问题?
欢迎有过经验的高手指正!
1.只是读操作,并且不会同时访问同一个元素。
2.没有删除操作,有添加。
考虑到多线程的效率,我不想加锁,请教高手,会不会出问题?
欢迎有过经验的高手指正!
|
我觉得这个问题不能孤立的看,还要看你是怎么设计的,会不会同时读同一个元素都无关紧要。主要的是你有添加操作。添加操作不加锁会有两个问题,1是两个线程同时添加,2是添加过程中另外一个线程读。加不加锁就看你怎么处理这两个问题。
如果你只有一个线程添加节点,问题1就不存在。如果你的添加节点只是一个指针的赋值操作,我觉得问题2也不是大问题,当然你可以争论说一个赋值操作转化成机器码也有很多操作,但是我们当年进程间通信用的循环列表指针用了那么多年好像也没出什么问题。
我想这样也回答了你最后的问题。如果你要解决问题1,你就加一个写的互斥锁,如果你认为问题2同样要解决你就给读加一个共享锁。如果你认为都不是问题,就不用加锁。
如果你只有一个线程添加节点,问题1就不存在。如果你的添加节点只是一个指针的赋值操作,我觉得问题2也不是大问题,当然你可以争论说一个赋值操作转化成机器码也有很多操作,但是我们当年进程间通信用的循环列表指针用了那么多年好像也没出什么问题。
我想这样也回答了你最后的问题。如果你要解决问题1,你就加一个写的互斥锁,如果你认为问题2同样要解决你就给读加一个共享锁。如果你认为都不是问题,就不用加锁。
|
我个人认为应该加锁,别的不说,主要是第二条里面的添加操作,你是否考虑过在链表的同一个位置有两个线程进行添加操作的情况?
假如说是单向链表,A->B,现在在A,B中间加上C,A->C,temp->B,其中temp为临时变量,那么如果现在另外一个线程来添加的话,怎么办?如果是在A->C中间,或者其他位置进行添加操作还好说,但是如果是在C之后添加,会出现什么情况,你可以考虑一下。现在C的后续指针还没有赋值啊。
我在这里只是说说我自己的想法,不一定正确,希望你批判的看待。而且我不是高手,呵呵,但是我非常喜欢和大家一起交流。
对于性能的追求是应该的,但是我认为这应该是在保证正确性的前提下来做的。
祝你好运。
假如说是单向链表,A->B,现在在A,B中间加上C,A->C,temp->B,其中temp为临时变量,那么如果现在另外一个线程来添加的话,怎么办?如果是在A->C中间,或者其他位置进行添加操作还好说,但是如果是在C之后添加,会出现什么情况,你可以考虑一下。现在C的后续指针还没有赋值啊。
我在这里只是说说我自己的想法,不一定正确,希望你批判的看待。而且我不是高手,呵呵,但是我非常喜欢和大家一起交流。
对于性能的追求是应该的,但是我认为这应该是在保证正确性的前提下来做的。
祝你好运。
|
最好加锁
你在链表上添加节点
实际上已经执行写操作了
肯定有的节点的next指针会变化
加锁也不是很麻烦啊
你在链表上添加节点
实际上已经执行写操作了
肯定有的节点的next指针会变化
加锁也不是很麻烦啊
|
对链表有读操作应该就有遍历吧,那是如何保证“不会同时访问同一个元素”的呢?
对于单、不循环的链表,如果a,b两个线程都要添加节点,代码都是:
new好了一个节点,填好数据,p也遍历到指向了尾,就差给p->next赋值了,线程a先做了这个赋值,认为节点a已被添加,可马上就被切换,线程b也做赋值,这就...
对于单、不循环的链表,如果a,b两个线程都要添加节点,代码都是:
new好了一个节点,填好数据,p也遍历到指向了尾,就差给p->next赋值了,线程a先做了这个赋值,认为节点a已被添加,可马上就被切换,线程b也做赋值,这就...
|
我的一个程序是读没加锁,写加了锁,不过我也不知道这会不会有问题
|
如果是只读访问,是不需要加锁的。