当前位置:网站首页>C#多线程学习笔记二
C#多线程学习笔记二
2022-06-10 13:42:00 【HollowKnightZ】
使用Thread的一些注意事项
线程可见
AllocateDataSlot、SetData、 GetData
variable var => thread t1,t2
(1) t1,t2 共享var => public 有“锁”的问题
(2) t1,t2 各自有一个var => internal 没有锁争用的问题
var slot = Thread.AllocateDataSlot("username");
//主线程上设置槽位,也就是说hello word只能被主线程读取,其他线程无法读取
Thread.SetData(slot, "hello word!!");
new Thread(() =>
{
Thread.SetData(slot, "hello!!");
var obj = Thread.GetData(slot);
Console.WriteLine("子线程:{0}",obj);
}).Start();
var obj2 = Thread.GetData(slot);
Console.WriteLine("主线程:{0}",obj2);
Console.ReadKey();
输出结果:属于情况(2)
性能提升版:ThreadStatic
[ThreadStatic]
static string username = "??!!";
static void Main(string[] args)
{
username = "hello word!!";
new Thread(() =>
{
username = "hello!!";
Console.WriteLine("子线程:{0}", username);
}).Start();
Console.WriteLine("主线程:{0}", username);
Console.ReadKey();
}
运行结果:属于情况(2)
ThreadLocal:也叫做线程可见性
ThreadLocal<string> local = new ThreadLocal<string>();
local.Value = "hello word!!";
new Thread(() =>
{
local.Value = "hello!!";
Console.WriteLine("子线程:{0}", local.Value);
}).Start();
Console.WriteLine("主线程:{0}", local.Value);
Console.ReadKey();
运行结果:属于情况(2)
总结
这些数据都是存放在线程环境快中,是线程的空间开销。
内存栏栅
release和debug的性能差异
实际项目中,发布版本都是release版本,而不是debug版本,因为release中做了一些代码和缓存的优化,比如将一些数据从memory中读取到CPU高速缓存中。这一操作可能会带来一些bug。
下面这段代码在release环境下出现主线程不能执行结束的问题。
var isStop = false;
Thread t = new Thread(() =>
{
var isSuccess = false;
while (!isStop)
{
isSuccess = !isSuccess;
}
});
t.Start();
Thread.Sleep(1000);
isStop = true;
t.Join();
Console.WriteLine("主线程执行结束");
Console.ReadKey();
从代码中可以发现两个线程在共用一个isStop变量,而线程t会将该变量加载到CPU Cache中,当主线程对isStop进行修改后,线程t感知不到。
两个解决方法:
1. 不要让多个线程去操作一个共享变量,否则容易出现问题。
2. 如果一定要这么做,则需要不进行缓存,每次都从memory中读取数据。
MemoryBarrier和VolatileRead
在此方法之前的内存写入都要及时从CPU Cache中更新到memory,在此方法之后的内存读取都要从memory中读取而不是CPU Cache。
MemoryBarrier:
var isStop = false;
Thread t = new Thread(() =>
{
var isSuccess = false;
while (!isStop)
{
Thread.MemoryBarrier();
isSuccess = !isSuccess;
}
});
t.Start();
Thread.Sleep(1000);
isStop = true;
t.Join();
Console.WriteLine("主线程执行结束");
Console.ReadKey();
VolatileRead:
var isStop = 0;
Thread t = new Thread(() =>
{
var isSuccess = false;
while (isStop != 1)
{
Thread.VolatileRead(ref isStop);
isSuccess = !isSuccess;
}
});
t.Start();
Thread.Sleep(1000);
isStop = 1;
t.Join();
Console.WriteLine("主线程执行结束");
Console.ReadKey();
边栏推荐
- 组装芯片难保竞争优势,痛定思痛的高通终于开始自研核心架构
- How to solve the problem that vmware tools are grayed out when VMware Workstation is installed
- [golang] when creating a structure with configuration parameters, how should the optional parameters be transferred?
- 大四应届毕业生,想自学软件测试,如何应对面试?
- 【笔记】74HC573的一些记录
- Ten easy-to-use cross browser testing tools to share, good things worth collecting
- Cardview usage and properties
- 618 大促来袭,浅谈如何做好大促备战
- markdown设置字体为红色
- 【无标题】音频蓝牙语音芯片,WT2605C-32N实时录音上传技术方案介绍
猜你喜欢

【笔记】74HC573的一些记录

【技术分析】探讨大世界游戏的制作流程及技术——前期流程篇
![[technical analysis] discuss the production process and technology of big world games - preliminary process](/img/8d/52cb98a617f690df310d6de5512ebc.png)
[technical analysis] discuss the production process and technology of big world games - preliminary process

H. 265 introduction to coding principles

解决VMware Workstation安装VMware Tools显示灰色的办法

Ultra detailed ffmpeg installation and simple use tutorial

【操作教程】如何正确使用海康demo工具配置通道上线?

二叉树和图1

Flutter Icon Stack LIsttitle...学习总结3

【云计算】多云管理平台和公有云两者之间是啥关系?
随机推荐
leetcode-56-合并区间
Record common functions in MySQL at work
Flutter Listview, Column, Row学习个人总结2
buuctf [PHP]XDebug RCE
聊聊消息中间件(1),AMQP那些事儿
leetcode-57-插入区间
Smart campus security channel and video monitoring solution
Gin blog 总结1
Kotlin practises. Take login as an example. Anko simply uses it
High performance practical Alibaba sentinel notes, in-depth restoration of Alibaba micro service high concurrency scheme
工作中记录MySQL中的常用函数
anaconda安装opencv(cv2),在jupyter notebook中使用
markdown设置字体为红色
TabLayout 使用详解(修改文字大小、下划线样式等)
buuctf [Jupyter]notebook-rce
苹果生产线迁离,说明5G工业互联、智能制造对中国制造帮助有限
智慧校园安全通道及视频监控解决方案
【解决】每次加载已经训练好的模型,生成的向量会有不同
为doc2vec生成训练向量的数据集
解决win10虚拟机和主机不能互相粘贴复制的问题