讨教多线程的两个问题

.Net技术 码拜 8年前 (2016-02-24) 737次浏览
本人用的vc#2012 + .net framework 4.0,碰到多线程的两个问题,讨教一下,谢谢。线程使用new Thread创建出来的。
第一个是,假如有一个共享变量,只在一个线程中写,在另外一个线程中读,读到数据的实时性要求不高,这次读的是写前的值,再多试几次就能拿到写后的值就可以了。这个情况下,不加锁能否可以,原因是加锁要多一个lock代码写着挺烦的。  之所以有这个问题,是不知道在读的时候,会不会原因是cache line回写,将刚刚写的值冲掉了。
第二个问题,当本人在主线程用Abort函数结束线程B的时候,假如线程B此时正好在lock函数里面,这种情况下,线程b被结束后,被lock的资源会被自动释放吗,谢谢。
解决方案

10

读线程在无论何种场合频率都大于写线程时,不加lock问题也不大,否则会出现写线程连写若干次而读线程只读到最后一次的情况,即使加了lock同样会出现,除非你不care中间的几个值。假如care一般都是写线程写入队列,读线程从队列中读取数据,而不是一个共享变量

35

你的程序没有 lock 的必要。
Abort 并不能正常结束线程,只是触发线程崩溃异常。所谓“被lock的资源”这个概念是无厘头的,原因是lock语句块并没有锁什么“资源”。有些人就是爱滥用“资源”这个字眼儿。在lock语句块中,没有什么锁什么“资源”,也就谈不上释放什么资源的说法。

10

引用 7 楼 abcmn1234 的回复:
Quote: 引用 4 楼 sp1234 的回复:

你的程序没有 lock 的必要。
Abort 并不能正常结束线程,只是触发线程崩溃异常。所谓“被lock的资源”这个概念是无厘头的,原因是lock语句块并没有锁什么“资源”。有些人就是爱滥用“资源”这个字眼儿。在lock语句块中,没有什么锁什么“资源”,也就谈不上释放什么资源的说法。

谢谢,例如说在线程B中,正在执行下面的代码
lock(mm)
{
…//正在这里执行的时候
}
这个时候主线程调用了 B.Abort,然后,主线程(或新开一个新线程)又想执行上述代码,是可行的吗,或说,这里的lock能够进去吗

理论上来说B.Abort这个函数应该没那么水,应该会自动处理你说的这些问题~~

25

看上去是生产/消费型的
假如是这样建议使用线程安全类列表,假如生产者远大于消费者,注意限流保证,以免积压过多
同时假如是本人个人会改成可限流阻塞队列,而不是仅仅一个简单类型变量
例如

 BlockingColletion<int> _blockQueue=new  BlockingColletion<int>(bounderCapactiy:1);//原因是你每次只要1个值,所以本人限流1,假如这个值没有用掉,该类本人会保持lock不用你管理

而接收线程里则会用可取消滴Task去订阅这个队列(目前的语法环境,本身建议弃用Theah线程,而使用Task代替)

Task t=new Task(()=>{
  while(!cancelToken.IsCancellationRequested) //假如没收到取消指令
{
    foreach(var item in __blockQueue.getConsumingEnumerable()) //取出队列里的缓存的值
{
    //这个item就是上次你压入队列的值,原因是上面限流了,实际上你也指取得到上次的,不过你这次你已经取了,所以生产者可以继续加
}
}
  
});
t.start()

10

1. 可以不使用锁
2.abort 不会吧锁释放

10

11楼上面的那个例子,个人认为是需要lock的。
一个比较宏观的例子,新线程有可能没有被实际执行而主线程先行执行,虽然可能性极低但这种极端情况是可能的。
从原理上说需不需要lock取决于你需不需要原子操作,实际上即使是基本类型变量的操作,只要是共享变量,加锁会是一个好的选择。或说假如你不确定需不需要加锁,那就请加锁,与读写无关。
即使在机器指令的层面也不能保证基本类型变量操作是原子操作,特别是在多处理器的系统上。一个例子是lz说的cache line的问题。
而假如你需要原子操作但不去加锁,程序移植,编译环境更新,os系统变化硬件环境变化都可能会引发问题。
当然假如是你说本人的程序只考虑目前的诸如单核环境,桌面客户端程序之类的,不考虑同步也不那么重要,99.99%可能都不会出现问题。但在服务器程序上,为了那0.01%加锁是值得的。
个人见解。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明讨教多线程的两个问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)