精易论坛

标题: 线程中变量安全操作类 [打印本页]

作者: jingyi11023995    时间: 2017-4-10 10:18
标题: 线程中变量安全操作类
本帖最后由 jingyi11023995 于 2017-4-10 11:14 编辑

因为自己写的一个软件,只是单线程,在不同电脑上运行,个别电脑出现闪退。
所以在本论坛和百度搜索易语言闪退的原因,看了不少文章和帖子,也做了不少的尝试。

有人说到:假如一个线程要对某个变量取值,而刚好这个时候有另外一个线程要对这个变量赋值,可能会出现错误。

于是,我想到了用自己的建的一个类,在类中用许可证来防止这种情况的发生。代码如下(只写了文本和整数的,其他类型照着写就行了):

  
窗口程序集名保 留  保 留备 注
线程中变量安全操作类, , 公开   
子程序名返回值类型公开备 注
_初始化 当基于本类的对象被创建后,此方法会被自动调用
调试输出 (“线程中变量安全操作类    _初始化”)
许可证 = 创建进入许可证 ()
子程序名返回值类型公开备 注
_销毁 当基于本类的对象被销毁前,此方法会被自动调用
删除进入许可证 (许可证)
子程序名返回值类型公开备 注
文本安全操作 
参数名类 型参考可空数组备 注
操作类型整数型0为取,1为赋值
文本变量文本型
赋值内容文本型
进入许可区 (许可证)
判断 (操作类型 = 0)

文本变量 = 赋值内容
退出许可区 (许可证)
子程序名返回值类型公开备 注
整数安全操作 
参数名类 型参考可空数组备 注
操作类型整数型0为取,1为赋值
整数变量整数型
赋值内容整数型
进入许可区 (许可证)
判断 (操作类型 = 0)

整数变量 = 赋值内容
退出许可区 (许可证)


i支持库列表   支持库注释   
spec特殊功能支持库
EThread多线程支持库


PS:刚测试了,失败,有没有大神帮忙看看?


补充内容 (2017-4-11 12:13):
解决了,代码在27楼。
作者: 醉看ジ笑红颜づ    时间: 2017-4-10 10:38
局部变量赋值哪能出错呢,主要是多个线程操作集或者全变量时要加锁,这反而有些画蛇添足了。
作者: jingyi11023995    时间: 2017-4-10 10:57
醉看ジ笑红颜づ 发表于 2017-4-10 10:38
局部变量赋值哪能出错呢,主要是多个线程操作集或者全变量时要加锁,这反而有些画蛇添足了。

我就是说在多线程中操作呀。你看第三行。
作者: jingyi11023995    时间: 2017-4-10 10:59
本帖最后由 jingyi11023995 于 2017-4-10 11:01 编辑
醉看ジ笑红颜づ 发表于 2017-4-10 10:38
局部变量赋值哪能出错呢,主要是多个线程操作集或者全变量时要加锁,这反而有些画蛇添足了。

例如这样的情况,如何加锁???
  
窗口程序集名保 留  保 留备 注
窗口程序集_启动窗口   
变量名类 型数组备 注
文本1文本型  
run逻辑型  
安全操作1线程中变量安全操作类  

子程序名返回值类型公开备 注
__启动窗口_创建完毕  
run = 真
子程序名返回值类型公开备 注
_按钮1_被单击  
启动线程 (&取值1, , )
启动线程 (&赋值1, , )
子程序名返回值类型公开备 注
取值1  
判断循环首 (run)
调试输出 (文本1)
延时 (1)
判断循环尾 ()
子程序名返回值类型公开备 注
赋值1  
判断循环首 (run)
文本1 = “abcdefg”到文本 (取随机数 (1, 100000))
延时 (1)
判断循环尾 ()


i支持库列表   支持库注释   
EThread多线程支持库
spec特殊功能支持库

作者: jingyi11023995    时间: 2017-4-10 11:06
jingyi11023995 发表于 2017-4-10 10:59
例如这样的情况,如何加锁???
[e=3].版本 2
.支持库 EThread

试试就知道了,用事实说话。
这些代码会出现输出乱码的。
作者: 醉看ジ笑红颜づ    时间: 2017-4-10 11:06
你如果说的是多线程 那按照我自己的理解,只需要把文本1赋值前后加锁即可,延时去掉。
作者: jingyi11023995    时间: 2017-4-10 11:08
jingyi11023995 发表于 2017-4-10 10:59
例如这样的情况,如何加锁???
[e=3].版本 2
.支持库 EThread

大哥,我说在单线程中出现闪退,然后说的是要解决多线程中的问题。能不能认真点看?
作者: jingyi11023995    时间: 2017-4-10 11:10
醉看ジ笑红颜づ 发表于 2017-4-10 11:06
你如果说的是多线程 那按照我自己的理解,只需要把文本1赋值前后加锁即可,延时去掉。

别空口说,试试~~
作者: 醉看ジ笑红颜づ    时间: 2017-4-10 11:17
一句话,单线程不需要加许可证,是不是傻?你问谁都是一样,不用加。
作者: jingyi11023995    时间: 2017-4-10 11:17
jingyi11023995 发表于 2017-4-10 10:59
例如这样的情况,如何加锁???
[e=3].版本 2
.支持库 EThread

@我是你亲表哥
文本1,不是全局变量 ,是程序集变量,如何加锁?测试过,没有乱码再告诉我,不要以为怎么样。
作者: jingyi11023995    时间: 2017-4-10 11:21
醉看ジ笑红颜づ 发表于 2017-4-10 11:17
一句话,单线程不需要加许可证,是不是傻?你问谁都是一样,不用加。

大哥,我都说了是多线程。。。。

_按钮1_被单击
启动线程 (&取值1, , )
启动线程 (&赋值1, , )

你加许可证,如果没乱码,我服你!
作者: 醉看ジ笑红颜づ    时间: 2017-4-10 11:21
乱码和闪退没半毛钱关系。
作者: jingyi11023995    时间: 2017-4-10 11:22
醉看ジ笑红颜づ 发表于 2017-4-10 11:21
乱码和闪退没半毛钱关系。

都不知道你到底有没有看我的帖子,我有说是为了解决闪退了吗????
作者: 醉看ジ笑红颜づ    时间: 2017-4-10 11:23
乱码造成的原因是取值和赋值的线程并不同步,
作者: jingyi11023995    时间: 2017-4-10 11:24
醉看ジ笑红颜づ 发表于 2017-4-10 11:23
乱码造成的原因是取值和赋值的线程并不同步,

你说说,一个线程取值,另一个线程赋值,如何保证不乱码。
作者: 醉看ジ笑红颜づ    时间: 2017-4-10 11:36
  
窗口程序集名保 留  保 留备 注
窗口程序集_启动窗口   
变量名类 型数组备 注
run逻辑型  
文本1文本型  
已赋值逻辑型  

子程序名返回值类型公开备 注
__启动窗口_创建完毕  
run = 真
启动线程 (&_按钮1_被单击, , )
子程序名返回值类型公开备 注
_按钮1_被单击  
启动线程 (&取值1, , )
启动线程 (&赋值1, , )
子程序名返回值类型公开备 注
取值1  
判断循环首 (run)
如果真 (已赋值)
调试输出 (文本1)
已赋值 = 假

判断循环尾 ()
子程序名返回值类型公开备 注
赋值1  
变量名类 型静态数组备 注
随机值整数型 
判断循环首 (run)
如果真 (已赋值 = )
随机值 = 取随机数 (1, 100000)
文本1 = “abcdefg”到文本 (随机值)
如果真 (寻找文本 (文本1, 到文本 (随机值), , ) ≠ -1)
已赋值 = 真


判断循环尾 ()


i支持库列表   支持库注释   
EThread多线程支持库
spec特殊功能支持库

作者: 醉看ジ笑红颜づ    时间: 2017-4-10 11:37
  
窗口程序集名保 留  保 留备 注
窗口程序集_启动窗口   
变量名类 型数组备 注
run逻辑型  
文本1文本型  
已赋值逻辑型  

子程序名返回值类型公开备 注
__启动窗口_创建完毕  
run = 真
启动线程 (&_按钮1_被单击, , )
子程序名返回值类型公开备 注
_按钮1_被单击  
启动线程 (&取值1, , )
启动线程 (&赋值1, , )
子程序名返回值类型公开备 注
取值1  
判断循环首 (run)
如果真 (已赋值)
调试输出 (文本1)
已赋值 = 假

判断循环尾 ()
子程序名返回值类型公开备 注
赋值1  
变量名类 型静态数组备 注
随机值整数型 
判断循环首 (run)
如果真 (已赋值 = )
随机值 = 取随机数 (1, 100000)
文本1 = “abcdefg”到文本 (随机值)
如果真 (寻找文本 (文本1, 到文本 (随机值), , ) ≠ -1)
已赋值 = 真


判断循环尾 ()


i支持库列表   支持库注释   
EThread多线程支持库
spec特殊功能支持库

作者: 醉看ジ笑红颜づ    时间: 2017-4-10 11:39
况且,许可证也不是你这么加的,放在返回后边? 真要是线程,你这么写只会导致程序停止(不是崩溃)就是不会往下运行了.
作者: 醉看ジ笑红颜づ    时间: 2017-4-10 11:40
两个子程序直接同步 就必须通知一下另一个子程序这边已经准备就绪了,或结束了再操作,这样浅显易懂了?
作者: jingyi11023995    时间: 2017-4-10 12:07
醉看ジ笑红颜づ 发表于 2017-4-10 11:39
况且,许可证也不是你这么加的,放在返回后边? 真要是线程,你这么写只会导致程序停止(不是崩溃)就是不会往下 ...

谢谢,这个在自己测试时已发现。
作者: jingyi11023995    时间: 2017-4-10 12:08
醉看ジ笑红颜づ 发表于 2017-4-10 11:40
两个子程序直接同步 就必须通知一下另一个子程序这边已经准备就绪了,或结束了再操作,这样浅显易懂了?

这两个线程是无限循环的,用互斥来控制,是吧?
作者: 克瑞斯    时间: 2017-4-10 12:59
提示: 作者被禁止或删除 内容自动屏蔽
作者: 荖貢    时间: 2017-4-10 20:00
你这方法不好 应该对全局共享数据做互斥操作, 而不是写到类里就能解决问题的,要根据实际情况写互斥
作者: jingyi11023995    时间: 2017-4-10 21:15
@xxdahai
类中是不能使用全局变量的。
作者: waiting2012    时间: 2017-4-11 07:54
在相互交流中提高!
作者: jingyi11023995    时间: 2017-4-11 11:53
醉看ジ笑红颜づ 发表于 2017-4-10 11:37
[e=0].版本 2
.支持库 EThread
.支持库 spec

感谢回复,那是我另一个帖子的内容。
另一种实现办法。

本贴是说的是想建一个类,在类中通过许可证来保证不同线程不能同时操作一个变量。
作者: jingyi11023995    时间: 2017-4-11 12:11
本帖最后由 jingyi11023995 于 2017-4-11 12:13 编辑
  
窗口程序集名保 留  保 留备 注
文本安全类, , 公开   
变量名类 型数组备 注
value文本型  
许可证整数型  

子程序名返回值类型公开备 注
_初始化 当基于本类的对象被创建后,此方法会被自动调用
许可证 = 创建进入许可证 ()
子程序名返回值类型公开备 注
_销毁 当基于本类的对象被销毁前,此方法会被自动调用
删除进入许可证 (许可证)
子程序名返回值类型公开备 注
Set_And_Get文本型 
参数名类 型参考可空数组备 注
赋值逻辑型
参数文本型
进入许可区 (许可证)
延时 (1)
如果真 (赋值)
value = 参数
退出许可区 (许可证)
返回 (value)


i支持库列表   支持库注释   
EThread多线程支持库


作者: waterbra    时间: 2017-4-14 22:34
有学到了。。。。
作者: 龙海软件    时间: 2017-4-15 17:17
666666来签个到,谢谢分享。
作者: xxdahai    时间: 2017-4-16 10:12
jingyi11023995 发表于 2017-4-10 21:15
@xxdahai
类中是不能使用全局变量的。

那我觉得这个程序类里面不要进行许可证的相关操作,而是在调用类之前先进入许可证,调用类,退出许可证
作者: xxdahai    时间: 2017-4-16 10:14
jingyi11023995 发表于 2017-4-10 21:15
@xxdahai
类中是不能使用全局变量的。

那我觉得这个程序类里面不要进行许可证的相关操作,而是在调用类之前先进入许可证,调用类,退出许可证
作者: xxdahai    时间: 2017-4-16 10:14
jingyi11023995 发表于 2017-4-10 21:15
@xxdahai
类中是不能使用全局变量的。

那我觉得这个程序类里面不要进行许可证的相关操作,而是在调用类之前先进入许可证,调用类,退出许可证




欢迎光临 精易论坛 (https://125.confly.eu.org/) Powered by Discuz! X3.4