[结贴]利用std::atomic实现一个lockfree结构,析构的时候崩溃了
本帖最后由 asker160 于 2017-01-04 23:20 编辑我照着cppreference的例子,为stack增加了一个析构函数:
#include<atomic>
template<class T>
struct node{
T data;
node* next;
node(const T&data):data(data),next(nullptr){}
};
template<class T>
class stack{
std::atomic<node<T>*> head;
public:
void push(const T&data)
{
node<T>* new_node=new node<T>(data);
new_node->next=head.load(std::memory_order_relaxed);
while(!std::atomic_compare_exchange_weak_explicit(
&head,
&new_node->next,
new_node,
std::memory_order_release,
std::memory_order_relaxed));
}
~stack(){ //我添加的函数
node<T>* p=head;
while(p) {
node<T>* next=p->next;
delete p;
p=next;
}
}
};
int main()
{
stack<int> s;
s.push(1);
s.push(2);
s.push(3);
return 0;
}
程序执行到~stack,最后一次delete的时候,出错了
$ g++ myatomic.cpp -std=c++11
$ ./a.out
*** Error in `./a.out': munmap_chunk(): invalid pointer: 0x0000000000400b00 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x1a8)
./a.out
./a.out
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)
./a.out
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 2506641 /home/x/cpp/x01/a.out
00601000-00602000 r--p 00001000 08:01 2506641 /home/x/cpp/x01/a.out
00602000-00603000 rw-p 00002000 08:01 2506641 /home/x/cpp/x01/a.out
022f6000-02328000 rw-p 00000000 00:00 0
7f0717022000-7f071712a000 r-xp 00000000 08:01 2102313 /lib/x86_64-linux-gnu/libm-2.23.so
7f071712a000-7f0717329000 ---p 00108000 08:01 2102313 /lib/x86_64-linux-gnu/libm-2.23.so
7f0717329000-7f071732a000 r--p 00107000 08:01 2102313 /lib/x86_64-linux-gnu/libm-2.23.so
7f071732a000-7f071732b000 rw-p 00108000 08:01 2102313 /lib/x86_64-linux-gnu/libm-2.23.so
7f071732b000-7f07174eb000 r-xp 00000000 08:01 2102243 /lib/x86_64-linux-gnu/libc-2.23.so
7f07174eb000-7f07176ea000 ---p 001c0000 08:01 2102243 /lib/x86_64-linux-gnu/libc-2.23.so
7f07176ea000-7f07176ee000 r--p 001bf000 08:01 2102243 /lib/x86_64-linux-gnu/libc-2.23.so
7f07176ee000-7f07176f0000 rw-p 001c3000 08:01 2102243 /lib/x86_64-linux-gnu/libc-2.23.so
7f07176f0000-7f07176f4000 rw-p 00000000 00:00 0
7f07176f4000-7f071770a000 r-xp 00000000 08:01 2102281 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f071770a000-7f0717909000 ---p 00016000 08:01 2102281 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f0717909000-7f071790a000 rw-p 00015000 08:01 2102281 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f071790a000-7f0717a7c000 r-xp 00000000 08:01 1312401 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f0717a7c000-7f0717c7c000 ---p 00172000 08:01 1312401 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f0717c7c000-7f0717c86000 r--p 00172000 08:01 1312401 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f0717c86000-7f0717c88000 rw-p 0017c000 08:01 1312401 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f0717c88000-7f0717c8c000 rw-p 00000000 00:00 0
7f0717c8c000-7f0717cb2000 r-xp 00000000 08:01 2102215 /lib/x86_64-linux-gnu/ld-2.23.so
7f0717e8e000-7f0717e93000 rw-p 00000000 00:00 0
7f0717eae000-7f0717eb1000 rw-p 00000000 00:00 0
7f0717eb1000-7f0717eb2000 r--p 00025000 08:01 2102215 /lib/x86_64-linux-gnu/ld-2.23.so
7f0717eb2000-7f0717eb3000 rw-p 00026000 08:01 2102215 /lib/x86_64-linux-gnu/ld-2.23.so
7f0717eb3000-7f0717eb4000 rw-p 00000000 00:00 0
7ffec8e19000-7ffec8e3a000 rw-p 00000000 00:00 0
7ffec8edb000-7ffec8edd000 r--p 00000000 00:00 0
7ffec8edd000-7ffec8edf000 r-xp 00000000 00:00 0
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 这个错误到底是怎么回事? 调试的时候是第三次delete的时候崩溃。没有发现程序有什么异常啊。
还请指教!
gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) 表示正常{:yct61:} 对那块内存加一个watch,看一下在执行哪行代码的时候出的问题 加了构造函数stack():head(nullptr){}就解决了。 你这倒是无锁, 就是有循环。。。。。。。。。。。。。。 zylthinking 发表于 2017-01-05 09:49
你这倒是无锁, 就是有循环。。。。。。。。。。。。。。
楼主的代码来源:http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange
没循环不可能,lock-free不等于wait-free
lxyscls 发表于 2017-01-05 14:02
楼主的代码来源:http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange
没循环不可能,l ...
死循环还不如锁,占资源啊!如果用在手机上,耗电,而且别的别干了。
回复 7# yulihua49
加锁的数据结构,多跑四五个线程(每个核跑一个),性能就上不去了,不光上不去,再多还往下掉,不带锁的,还有希望。
死不死循环,还是看数据来源。数据没了,还可以选择用户态pause,要是一直没有,干脆就把调度交出去。
本帖最后由 yulihua49 于 2017-01-09 18:41 编辑
lxyscls 发表于 2017-01-09 09:22
回复 7# yulihua49
加锁的数据结构,多跑四五个线程(每个核跑一个),性能就上不去了,不光上不去,再 ...
消费者得不到数据,死循环等?超过5个线程能比加锁性能高?32核弄32个线程没事死循环等?服务器嗷嗷叫。
如果挂起,还要等事件解挂,跟等锁一样啊!那不就是条件锁吗?
我测试解一次锁大约3~7微秒,是比较慢。
本帖最后由 yulihua49 于 2017-01-09 18:56 编辑
lxyscls 发表于 2017-01-09 09:22
回复 7# yulihua49
加锁的数据结构,多跑四五个线程(每个核跑一个),性能就上不去了,不光上不去,再 ...
我们这样的:
queue
mutex_lock
cond_lock
消费者:
lock(&mutex_lock);
while(!(p=get(queue))) {//没有资源
cond_wait(&cond_lock,&mutex_lock);//消费者在此挂起等待,用户态pause。你会比他效率高?
}
unlock(&mutex_lock);
//p得到资源。
........
生产者:
lock(&mutex_lock);
add(queue,data);
unlock(&mutex_lock)
cond_signal(&cond_lock);//给消费者发信号解锁;
........
页:
[1]
2