线程如何访问全局变量,线程可以通过进程的全局变量
关于线程并发访问全局变量问题
我怎么觉得都可能呢?
假设线程x和y同时执行,x和y可随时被抢占,a的初始值为1
A:3, 2
y先执行++a,a为2;
y再执行printf,a入栈,在打印到终端之前切换到x
x执行++a,a为3;
x执行printf,输出3;再切换到y
y执行打印,输出2
B:2 3
x先执行++a,a为2;
x再执行printf,输出2;切换到y
y执行++a,a为3;
y执行printf,输出3;
C:3 3
x先执行++a,a为2;切换到y
y执行++a,a为3;
y执行printf,输出3;切换到x
x执行printf,输出3
D:2 2
类似C,a的初始值为0即可
这里关键有两点:
(1)两个线程可随时被抢占
(2)++a和printf不是原子指令,可随时被打断;特别注意函数printf,a作为参数压栈后,a再变化则不会影响输出(printf实际打印的是压栈的参数,是值拷贝的栈变量)
TCL中如何在子线程中访问全局函数或者全局变量
set procedure to kk 是打开过程文件
public x,y 定义全局变量,全局有效
private 是在过程中屏蔽public定义的变量,即私有变量,离开过程,就会实效。
local 定义局部变量,作用域只在本过程。
x=30 是赋值语句,将30赋给x
public x,y 定义全局变量
set proc to kk 打开过程文件
x=20 全局变量赋值
y=50
do a1 执行过程a1
?x,y
set proc to
return
*过程序文件kk.prg
proc a1
private x 定义私有变量,屏蔽调用过程的x
x=30 x=30
local y 定义局部变量,y为逻辑假
do a2 执行a2
?x,y
return
proc a2
x="kkk" x赋值,x如果脱离a2过程,x变成全局变量,即x=20
y="mmm" y从a1过程出来,变成全局变量,重新赋值“mmm”
return
看着我的解释导顺序,就会明白的

线程之间如何调用变量
如楼上所说,线程的局部变量是无法互相调用的,可以声明一些全局变量。但需要在声明的时候bool前面加volatile,如果不加,很有可能你在2个线程中访问同一个变量时,2个变量的值是不一样的,因为编译器会进行优化。简单点说就是编译器在进行2个线程的处理时,都将该变量读入一个临时内存保存起来,在使用时直接使用,因为这样速度更快,而在变量前加volatile的目的是告诉编译器不要优化这个变量,每次使用他时,都从寄存器中读取,所以一当这个变量的值有变动时,只要有对它进行访问,都能拿到最新的数据。
如volatile bool IsNextData;
否则编译器会进行优化
IsNextData直接从寄存器中取值,而不访问内存。
而你在另一个线程中改变的事IsNextData内存中的值。
跟踪也是访问内存的值。
给你百科对volatile的解释:
多线程对全局变量的操作
1. 初始化的时候, 如果线程A执行完毕的时候, 线程B还没有运行(相信这个时候C还没有创建), 那么g_str肯定存的是初始化时读取的值.
线程B要按button才调用, 如果一直没有按button, 就一直没有调用. 所以正常情况下你的程序都只有运行线程C, 你可以确认一下:
a) 初始化后线程A, 有没有结束
b) 不按button, g_str的赋值是否正确? 如果不按button都不正确, 那么你的线程C的赋值本身就有问题. 注意看你怎么判断赋值成功, 或者赋值错了? 在什么时间点判断g_str的赋值出错.
2. 你的情况线程B是随机发生的, 与线程C有冲突, 如果只是为了访问不冲突的话, 一般为g_str加个互斥就可以. 对g_str有特殊的使用点要求(对读取的时间点有要求)的话, 才要考虑同步的问题.