Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在c中使用多线程遍历TwinCat中的非二进制树状结构#_C#_Multithreading_Tree_Stream_Twincat - Fatal编程技术网

C# 在c中使用多线程遍历TwinCat中的非二进制树状结构#

C# 在c中使用多线程遍历TwinCat中的非二进制树状结构#,c#,multithreading,tree,stream,twincat,C#,Multithreading,Tree,Stream,Twincat,我正在尝试优化搜索算法,通过ADS界面在TwinCat 3中查找标记符号。这个问题与TwinCat无关,所以不要害怕 问题是: 符号不会立即加载。我认为TwinCatAds库使用延迟加载。 符号具有非二叉非平衡树的树状结构 解决方案: 您可以打开多个ADS流,并在多个线程中处理这些流 问题是,我将第一级符号除以处理器内核的数量。因此,由于树是不平衡的,一些线程比其他线程完成得更快。因此,我需要一个更好的解决方案,如何在线程之间分配工作 PS:我不能使用Parallel.ForEach()。由于流

我正在尝试优化搜索算法,通过ADS界面在TwinCat 3中查找标记符号。这个问题与TwinCat无关,所以不要害怕

问题是: 符号不会立即加载。我认为TwinCatAds库使用延迟加载。 符号具有非二叉非平衡树的树状结构

解决方案: 您可以打开多个ADS流,并在多个线程中处理这些流

问题是,我将第一级符号除以处理器内核的数量。因此,由于树是不平衡的,一些线程比其他线程完成得更快。因此,我需要一个更好的解决方案,如何在线程之间分配工作

PS:我不能使用Parallel.ForEach()。由于流的原因,它会产生与单线程解决方案相同或更大的时间量

我的测试代码是这样的,它只计算一个大型项目的所有符号

using TwinCAT.Ads;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.Collections;


namespace MultipleStreamsTest
{
class Program
{
    static int numberOfThreads = Environment.ProcessorCount;
    static TcAdsClient client;
    static TcAdsSymbolInfoLoader symbolLoader;
    static TcAdsSymbolInfoCollection[] collection = new TcAdsSymbolInfoCollection[numberOfThreads];
    static int[] portionResult = new int[numberOfThreads];
    static int[] portionStart = new int[numberOfThreads];
    static int[] portionStop = new int[numberOfThreads];

    static void Connect()
    {
        client = new TcAdsClient();
        client.Connect(851);
        Console.WriteLine("Conected ");
    }
    static void Main(string[] args)
    {
        Connect();
        symbolLoader = client.CreateSymbolInfoLoader();
        CountAllOneThread();
        CountWithMultipleThreads();
        Console.ReadKey();
    }        
    static public void CountAllOneThread()
    {
        Stopwatch stopwatch = new Stopwatch();
        int index = 0;
        stopwatch.Start();
        Console.WriteLine("Counting with one thread...");
        //Count all symbols
        foreach (TcAdsSymbolInfo symbol in symbolLoader)
        {                
            index++;
        }
        stopwatch.Stop();
        //Output
        Console.WriteLine("Counted with one thred " + index + " symbols in " + stopwatch.Elapsed);
    }
    static public int countRecursive(TcAdsSymbolInfo symbol)
    {
        int i = 0;
        TcAdsSymbolInfo subSymbol = symbol.FirstSubSymbol;
        while (subSymbol != null)
        {
            i = i + countRecursive(subSymbol);
            subSymbol = subSymbol.NextSymbol;
            i++;
        }
        return i;
    }
    static public void countRecursiveMultiThread(object portionNum)
    {
        int portionNumAsInt = (int)portionNum;
        for (int i = portionStart[portionNumAsInt]; i <= portionStop[portionNumAsInt]; i++)
        {
                portionResult[portionNumAsInt] += countRecursive(collection[portionNumAsInt][i]);//Collection Teil 
        }
    }
    static public void CountWithMultipleThreads()
    {
        Stopwatch stopwatch = new Stopwatch();
        int sum = 0;
        stopwatch.Start();
        Console.WriteLine("Counting with multiple thread...");
        for (int i = 0; i < numberOfThreads; i++)
        {
            collection[i] = symbolLoader.GetSymbols(true);
        }
        int size = (int)(collection[0].Count / numberOfThreads);
        int rest = collection[0].Count % numberOfThreads;
        int m = 0;
        for (; m < numberOfThreads; m++)
        {
            portionStart[m] = m * size;
            portionStop[m] = portionStart[m] + size - 1;
        }
        portionStop[m - 1] += rest;

        Thread[] threads = new Thread[numberOfThreads];
        for (int i = 0; i < numberOfThreads; i++)
        {
            threads[i] = new Thread(countRecursiveMultiThread);
            threads[i].Start(i);
            Console.WriteLine("Thread #" + threads[i].ManagedThreadId + " started, fieldIndex: " + i);
        }
        //Check when threads finishing:
        int threadsFinished = 0;
        bool[] threadFinished = new bool[numberOfThreads];
        int x = 0;
        while (true)
        {
            if (threads[x].Join(10) && !threadFinished[x] )
            {
                Console.WriteLine("Thread #" + threads[x].ManagedThreadId + " finished ~ at: " + stopwatch.Elapsed);
                threadsFinished++;
                threadFinished[x] = true;                    
            }
            x++;
            x = x % numberOfThreads;
            if (threadsFinished == numberOfThreads) break;
            Thread.Sleep(50);
        }            
        foreach (int n in portionResult)
        {
            sum += n;
        }
        sum += collection[0].Count;
        stopwatch.Stop();
        //Output
        Console.WriteLine("Counted with multiple threds in Collection " + sum + " symbols " + " in " + stopwatch.Elapsed);
        for (int i = 0; i < numberOfThreads; i++)
        {
            Console.WriteLine("#" + i + ": " + portionResult[i]);
        }
    }
}
}
使用TwinCAT.Ads;
使用系统线程;
使用System.IO;
使用系统诊断;
使用系统集合;
命名空间MultipleStreamST
{
班级计划
{
静态int numberOfThreads=Environment.ProcessorCount;
静态tcads客户端;
静态TcAdsSymbolInfoLoader符号加载程序;
静态TcAdsSymbolInfoCollection[]集合=新TcAdsSymbolInfoCollection[numberOfThreads];
静态int[]portionResult=newint[numberOfThreads];
static int[]portionStart=new int[numberOfThreads];
静态int[]portionStop=newint[numberOfThreads];
静态void Connect()
{
client=新的TcAdsClient();
client.Connect(851);
控制台。写入线(“连接”);
}
静态void Main(字符串[]参数)
{
Connect();
symbolLoader=client.CreateSymbolInfoLoader();
CountAllOneThread();
CountWithMultipleThreads();
Console.ReadKey();
}        
静态公共void CountAllOneThread()
{
秒表秒表=新秒表();
int指数=0;
秒表。开始();
Console.WriteLine(“单线程计数…”);
//数一数所有符号
foreach(符号加载程序中的TcAdsSymbolInfo符号)
{                
索引++;
}
秒表;
//输出
Console.WriteLine(“以“+秒表.已过”中的一个红色“+索引+”符号计数);
}
静态公共整数计数递归(TcAdsSymbolInfo符号)
{
int i=0;
TcAdsSymbolInfo subSymbol=symbol.FirstSubSymbol;
while(子符号!=null)
{
i=i+countRecursive(子符号);
subSymbol=subSymbol.NextSymbol;
i++;
}
返回i;
}
静态公共void countRecursiveMultiThread(对象portionNum)
{
int-portionNumAsInt=(int)portionNum;

对于(int i=portionStart[portionNumAsInt];i创建一个线程池,并跟踪线程的运行和空闲状态。在每个分支上检查是否有空闲线程,是否有将线程分配给子分支