c#中多线程和for循环计数器的问题
本文关键字:计数器 问题 循环 for 多线程 | 更新日期: 2023-09-27 18:04:43
我目前正在使用Unity引擎和c#创建一个游戏,我在其中生成一个游戏世界。目前,它存在一个预定大小的字节[,](在512到4096之间,因此对于总大小为4096x4096=16,7百万块)。在实现一个方法的多线程变体时,它随机地用1或2填充我的数组,这取决于一个随机生成器,我偶然发现了一个非常奇怪的问题。
下面是我的代码:void CellularAutomata()
{
int ThreadCount = Environment.ProcessorCount; //Amount of cores. 4 in my case
ThreadCount *= 4; // Multiplying by 4 to get higher amount of threads.
int ThreadWorkSizeX = WorldProps.Size.x / ThreadCount; //Divide map x size by threadcount
int ThreadWorkSizeY = WorldProps.Size.y / ThreadCount; // same for y
Thread[] Threads = new Thread[ThreadCount]; //create simple array
//Main thread nog mee laten werken
for (int i = 0; i < ThreadCount; i++) //for loop to create threads
{
UnityEngine.Debug.Log(i); // 0
Threads[i] = new Thread(() => {
UnityEngine.Debug.Log("Thread says " + (i)); // i is 1???
//Doing i-1 to correct this, but give unpredictable results.
for (int x = ( (i-1) * ThreadWorkSizeX); x < (( (i-1) * ThreadWorkSizeX) + ThreadWorkSizeX); x++)
{
for (int y = ( (i-1) * ThreadWorkSizeY); y < (( (i-1) * ThreadWorkSizeY) + ThreadWorkSizeY); y++)
{
if (WorldProps.RandomGen.Next(0, 100) < CellProps.FillPercentage)
{
TileTypeXZ[x, y] = 2;
}
else
{
TileTypeXZ[x, y] = 1;
}
}
}
});
//Inserting a debug.log here affects the results?
Threads[i].Start();
}
//Joining up again with my threads.
//(Yes i know, main thread not really doing anything yet, but i want this working first.)
for (int p = 0; p < ThreadCount; p++)
{
Threads[p].Join();
}
}
所有这些都是在这个简单的方法中完成的。它目前显然还没有完全实现元胞自动机算法,但它必须在未来。我首先想让多线程随机填充我的地图工作。整个过程完全包含在这个方法中,除了我的WorldProps对象之外,没有外部变量能够影响这个方法,这个对象只包含一些与世界大小等相关的变量。这不是问题所在。
因此,我想分割我的世界,这是一个二维字节数组,并分配给每个线程我的世界的一部分来填充。然而,在这里,我碰到了一些严重的问题。首先,我还尝试在for循环后手动启动每个线程,但这导致i总是等于线程的数量(在我的情况下为16),所以这是一个不去,但现在有这个奇怪的问题,当我创建一个新的线程对象时,突然我的'i'变量被增加了一个。通过使用(i-1)来纠正这个问题确实给了我一些结果,如果我修改for循环,(所以现在忽略i-1)但是当使用多个线程时它会停止工作。
由于某些原因放置Debug.Log ("Something");在指定的行上影响线程正在创建的结果。
很抱歉我的英语很差,因为我才17岁,还没有掌握这门语言。
无论如何,
有没有人在这里任何线索为什么我有这些奇怪的问题与这个循环计数器?多谢,
所有线程共享对i
的相同引用。使用临时变量
这是你的问题代码
for(int i=0; i < 10; i++)
{
new Thread(() => {
Console.WriteLine(i);
})
.Start();
}
改为:
for(int i=0; i < 10; i++)
{
var j = i;
new Thread(() => {
Console.WriteLine(j);
})
.Start();
}
有关闭包的更多信息: http://www.codethinked.com/c-closures-explained