多线程 栈空间变量 可见性

来源:互联网 发布:mac系统怎么关闭后台 编辑:程序博客网 时间:2024/06/04 19:39

今天看couchbase 回调代码的时候发现 callback 函数有一个参数是 cookie,相当于一个调用异步函数时的上下文。

http://docs.couchbase.com/developer/c-2.4/c-intro.html

我们代码里面是类似这样用的。


// 回调函数

static void get_callback(lcb_t instance,
        const void* cookie,
        lcb_error_t code,
        const lcb_get_resp_t* resp) {

//....修改 cookie

}


// instance, install 回调函数

lcb_t cb;

lcb_set_get_callback(cb, get_callback);


// 从couchbase取数据

std::deque<int64_t> uids;

lcb_get(cb, &uids, MAX_ITEMS, pcmds);


因为取数据的线程和调用回调函数的线程是两个不同的线程,

而uids是取数据的线程所在的栈上的,回调函数怎么可以直接操作这个变量呢?

不是一直说同一个进程的多个线程共享堆,但是都有自己的栈么?


恩,是的,这个说法是没错,线程有自己的栈,但是不代表它不能访问其他的线程的栈。


深入理解计算机系统 P663 是这样说的:

“各自独立的线程栈的存储器模型不是那么整齐清楚的。这些栈被保存在虚拟地址空间的栈区域中,并且通常是被相应的线程独立访问的。

我们说通常而不是总是,是因为不同的线程栈是不对其他线程设防的。所以,如果一个线程以某种方式得到一个指向其他线程栈的指针,那么他就可以读写这个栈的任何部分”


下面是测试代码。


#include <thread>#include <iostream>using namespace std;void func(int* pa) {  cout << pa << endl;  cout << *pa << endl;  *pa = 15;}int main() {  int a = 5;  cout << "main, &a: " << &a << endl;  thread thrd(func, &a);  thrd.join();  cout << "main, &a: " << &a << endl;  cout << "main, a: " << a << endl;}

[root@licchen-test-dev001-bjdxt tests]# g++ -std=c++11 -lpthread thread_2.cpp [root@licchen-test-dev001-bjdxt tests]# ./a.out main, &a: 0x7ffff5ae95640x7ffff5ae95645main, &a: 0x7ffff5ae9564main, a: 15


a 的值被另外的线程修改。



0 0
原创粉丝点击