我目前正在使用Unity引擎和C#构建游戏,其中我生成了一个游戏世界。目前,它存在预定大小的字节[,],(在512和4096之间,因此总大小为4096×4096 = 16,700万个区块)。在实现一个方法的多线程变体,该方法随机地使用依赖于随机生成器的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();
}
}
这一切都是通过这种简单的方法完成的。它目前显然还没有完全实现Cellular Automata算法,但它必须在未来。我首先想让多线程随机填充我的地图。整个过程完全包含在这个方法中,除了我的WorldProps对象之外,没有任何能够影响这个方法的外部变量,它只包含一些与世界大小相关的变量等。这不是问题所在。
因此,我想分割我的世界,这是一个二维的字节数组,并为每个线程分配我的世界的一部分来填充。然而,在这里,我遇到了一些严重的问题。首先我还尝试在for循环后手动启动每个线程,但这导致我总是等于线程数量(在我的情况下为16),所以这是一个不行,但现在有这个奇怪的问题当我创建一个新的Thread对象,突然我的'i'变量增加1。通过使用(i-1)来纠正这个确实给了我一些结果,如果我修改for循环,(所以现在忽略i-1)但是当使用多个单独的线程时它停止工作。
出于某种原因放置Debug.Log(“Something”);在指定的行上影响我的线程正在创建的结果。
对不起我的英语不好,我还没掌握这门语言,因为我才17岁。
无论哪种方式,
有没有人在这里有任何线索为什么我有这个for循环计数器这些奇怪的问题? 非常感谢,
答案 0 :(得分:3)
所有主题共享与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();
}
将其更改为:
<form id="myContainer" method="post" action=[?]></form>