多线程 栈空间变量 可见性

3 篇文章 0 订阅

今天看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: 0x7ffff5ae9564
0x7ffff5ae9564
5
main, &a: 0x7ffff5ae9564
main, a: 15


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



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值