作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在从事有关烘焙算法的项目,但我没有使用 C# 编写该算法的任何演示。由于这种情况,我转换了一些在维基百科上找到的 Java 代码。但无论如何,它似乎不起作用!
已更新:这是我的完整代码(旧代码包含在“//”注释中)
namespace BakeryAlgorithm
{
class Program
{
static int threads = 10;
static string x = "";
static int count = 0;
static int[] ticket = new int[threads];
static bool[] entering = new bool[threads];
public static void doLock(int pid)
{
entering[pid] = true;
int max = 0;
for (int i = 0; i < threads; i++)
{
if (ticket[i] > ticket[max]) { max = i; }
}
ticket[pid] = 1+max;
entering[pid] = false;
for (int i = 0; i < threads; ++i)
{
if (i != pid)
{
while (entering[i])
{
Thread.Yield();
}
while (ticket[i] != 0 && (ticket[pid] > ticket[i] ||
(ticket[pid] == ticket[i] && pid > i)))
{
Thread.Yield();
}
}
}
if (x == "C" || x == "c")
Console.WriteLine("[System] PID " + pid.ToString() + " get into critical section");
}
public static void unlock(int pid)
{
ticket[pid] = 0;
count++;
Console.WriteLine("[Thread] PID " + pid.ToString() + " process completed");
}
public static void arrayInit()
{
for (int i = 0; i < threads; i++)
{
ticket[i] = 0;
entering[i] = false;
}
}
public static void simThread(int i)
{
doLock(i);
if (x == "C" || x=="c")
Console.WriteLine("[Thread] PID " + i.ToString() + " begin to process...");
Random rand = new Random((int)DateTime.Now.Ticks & 0x0000FFFF);
int a = rand.Next(5,10);
int b = rand.Next(1,5);
int c = rand.Next(1,4);
double d = 0;
string o="";
if (c == 1)
{
d = a + b;
o=" + ";
}
else if (c == 2)
{
d = a * b;
o=" * ";
}
else if (c == 3)
{
d = a / b;
o=" / ";
}
else
{
d = a - b;
o=" - ";
}
if (x == "C" || x == "c")
Console.WriteLine("Result of PID " +i.ToString() +" : " + a.ToString() + o + b.ToString() + "=" + d.ToString());
unlock(i);
}
[STAThread]
static void Main(string[] args)
{
arrayInit();
string choice="C";
while (choice == "C" || x == "c")
{
Console.WriteLine("Do you want to see progress log ? (C=Yes,K=No) : ");
x = Console.ReadLine();
if (x == "")
x = "C";
Console.Clear();
Console.WriteLine("----------------------------------");
Console.WriteLine("Bakery Algorithm in C#");
Console.WriteLine("Number of threads : " + threads.ToString());
Console.WriteLine("Progress Log");
Console.WriteLine("----------------------------------");
Thread[] threadArray = new Thread[threads];
for (int i = 0; i < 10; i++)
{
//New code that solved my problem
int copy = i;
threadArray[i] = new Thread(() => simThread(copy));
//My old code that cause my problem
//threadArray[i] = new Thread(() => simThread(i));
if (x == "C" || x == "c")
Console.WriteLine("[System] PID " + i.ToString() + " has been created");
threadArray[i].Start();
Thread.Sleep(20);
}
Console.ReadLine();
Console.WriteLine("----------------------------------");
Console.WriteLine("Process completed " + count.ToString() + " threads !");
count = 0;
Console.WriteLine("----------------------------------");
Console.WriteLine("Do you want to restart the algorithm (C=Yes,K=No)");
choice = Console.ReadLine();
if (choice == "")
choice = "C";
}
}
}
}
最佳答案
问题是:
threadArray[i] = new Thread(() => simThread(i));
您在此处捕获 i
- 将在循环过程中更新的单个变量,并以 threads
的值结束。
如果线程只是在循环完成后才实际执行 lambda 表达式的主体,那么该值基本上是不合适的……即使不合适,您也可以轻松地拥有多个使用相同的 i
值的线程。
您基本上需要为循环的每次迭代使用一个单独的变量,例如
for (int i = 0; i < threads; i++)
{
int copy = i;
threadArray[i] = new Thread(() => simThread(copy));
Console.WriteLine("[He Thong] PID " + i.ToString() + " duoc khoi tao");
threadArray[i].Start();
}
这样,循环的每次迭代都会捕获一个单独的变量,该变量在该次迭代中的值为 i
,但随后不会更改。
这是您当前代码和工作代码之间的最小变化 - 但就我个人而言,我希望进行更大的更改以更多地使用 TPL,使用单独的独立对象而不是 parallel arrays等等
关于c# - 使用参数创建新线程时索引超出范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29745205/
我是一名优秀的程序员,十分优秀!