当前位置: 移动技术网 > IT编程>开发语言>.net > C#中多线程中变量研究

C#中多线程中变量研究

2019年06月26日  | 移动技术网IT编程  | 我要评论

重生洪荒之盘古同源,小三不能有幸福,蒂芬妮的香榭大道

今天在知乎上看到一个问题【为什么在同一进程中创建不同线程,但线程各自的变量无法在线程间互相访问?】。在多线程中,每个线程都是独立运行的,不同的线程有可能是同一段代码,但不会是同一作用域,所以不会共享。而共享内存,并没有作用域之分,同一进程内,不管什么线程都可以通过同一虚拟内存地址来访问,不同进程也可以通过ipc等方式共享内存数据。全局变量:任何线程都可以访问;局部变量(栈变量):任何线程执行到该函数时均可访问,函数外不可访问;线程变量:每个线程只能访问自己的那个拷贝,其他线程不可见。今天就用c#来实现同一段代码的不同线程,全局变量、局部变量、线程变量。

了解进程与线程

什么是多任务,简单来说就是操作系统同时可以运行多个任务。例如:一遍听歌,一遍写文档等。多核cpu可以执行多任务,但是单核cpu也可以执行多任务,cpu是顺序执行的,操作系统让任务轮流执行,例如:听歌执行一次,停顿0.01s,写文档执行一次,停顿0.01s等等。由于cpu的执行速度很快,我们感觉就像所有的任务都是同时执行。对操作系统来说,一个任务就是一个进程,一个进程至少有一个线程。进程是资源分配的最小单位,线程是cpu调度的最小单位。

普通的程序写法

private static list<int> data = enumerable.range(1, 1000).tolist();

public static void simpletest()
{
    for (int i = 0; i < 10; i++)
    {
        list<int> tempdata = new list<int>();
        foreach (var d in data)
        {
            tempdata.add(d);
        }
        console.writeline($"i:{i},合计:{data.sum()},是否相等:{data.sum() == tempdata.sum()}");
    }

    console.writeline("单线程运行结束");
}

多线程写法

private static list<int> data = enumerable.range(1, 1000).tolist();

public static async task moretasktestasync()
{
    list<task> tasks = new list<task>();
    for (int i = 0; i < 10; i++)
    {
        var tempi = i;
        var t = task.run(() =>
        {
            list<int> tempdata = new list<int>();
            foreach (var d in data)
            {
                tempdata.add(d);
            }
            console.writeline($"i:{tempi},合计:{data.sum()},是否相等:{data.sum() == tempdata.sum()}");
        });
        tasks.add(t);
    }

    await task.whenall(tasks); //或者task.waitall(tasks.toarray());
    console.writeline("多线程运行结束");
}

不同的线程同一段代码,但不会是同一作用域,所以tempdata数据没有互相影响。

全局变量:data,多个线程都可以访问,list只读的时候是线性安全
局部变量:i就是局部变量,访问的线程可以访问,去掉【var tempi = i;】,运行结果打印出来,值都是一样的,增加的都是每个线程都访问单独的tempi变量

i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true
i:10,合计:500500,是否相等:true

线程变量:tempdata,每个线程只访问自己的,互不影响,运行结果

i:3,合计:500500,是否相等:true
i:6,合计:500500,是否相等:true
i:0,合计:500500,是否相等:true
i:1,合计:500500,是否相等:true
i:4,合计:500500,是否相等:true
i:2,合计:500500,是否相等:true
i:7,合计:500500,是否相等:true
i:5,合计:500500,是否相等:true
i:8,合计:500500,是否相等:true
i:9,合计:500500,是否相等:true

写多线程的时候需要注意,变量的作用域,否则程序运行出来的结果将不会是想要的结果,注意,注意变量作用域。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网