Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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# 在Mono.Net线程中,线程是否会粘住,或者?_C#_C_.net_Multithreading_Unity3d - Fatal编程技术网

C# 在Mono.Net线程中,线程是否会粘住,或者?

C# 在Mono.Net线程中,线程是否会粘住,或者?,c#,c,.net,multithreading,unity3d,C#,C,.net,Multithreading,Unity3d,这是Unity/Mono,但任何.Net 想象一下这样的代码 using System.Threading; using System.Runtime.InteropServices; public class Example: MonoBehaviour { [DllImport("__Internal")] private static extern void long_function(); [DllImport("__Internal")] private stati

这是Unity/Mono,但任何.Net

想象一下这样的代码

using System.Threading;
using System.Runtime.InteropServices;

public class Example: MonoBehaviour {

    [DllImport("__Internal")] private static extern void long_function();
    [DllImport("__Internal")] private static extern void short_function();
    public Thread happyThread;
    public void Test() {

        happyThread = new Thread(LongTest);
        happyThread.Start();
    }
    private void LongTest() { long_function(); }
    private void ShortTest() { short_function(); }
}
我们运行
Test
,从而启动了C库中的
long_函数。它是在另一个线程上启动的。(“快乐阅读”)

假设运行需要60秒

  • 在这段时间结束时,
    happyThread
    是否不再存在?或者它仍然存在于示例范围中?或者你能保留它还是什么

  • 假设我们知道
    long\u函数已完成。然后我想调用
    ShortTest
    ,从而调用
    short\u函数
    。你能这样做吗

  • 早些时候我们这样做了

            happyThread = new Thread(LongTest);
    
    我们现在可以将线程的“内容”更改为

            happyThread.newStuff( ShortTest());
            happyThread.StartAgain();
    
    happyThread.newStuff( ShortTest());
    happyThread.StartAgain();
    
    或者这是愚蠢和毫无意义的

  • 我会仅仅在另一个新线程上再次开始短测试吗

  • 假设库有一个简单的全局变量
    intk

  • 因此TBC,构建到静态库中的C文件在顶部如下所示:

    //文件happyLibrary.c Fattie(TM)2019
    #包括
    #包括
    int k=7;//(注意,在真正的应用程序中,您几乎肯定希望使用volatile)
    空长函数
    {
    ...
    
  • …哪个
    long\u函数
    设置为42。事实上,
    short\u函数
    以后也可以访问该值吗?或者?仅当我使用相同的线程或其他东西时?同样,
    k
    是全局函数

  • 如果你不得不启动无数的小任务,如果重复使用happyThread可能有性能优势,如果你可以重用它们

  • (我完全理解,简单地说,long_函数将继续存在,并使用short_函数概念提供对主线程的回调;但是,呃,我想知道我上面问的是什么。你能“重复使用”线程吗?你能“再次使用”它吗?)

  • 在那个时候结束时,happyThread是否不再存在?或者它仍然存在于示例范围内?或者你能保留它或其他东西吗
  • 当线程上调用的函数(在本例中为
    LongTest
    )完成时,线程的生命周期将结束。只要您在
    happyThread
    (您可以自己查看!
    happyThread.ManagedThreadId
    即使完成后仍将返回线程的ID),但无法重新启动。您可以通过调用
    happyThread.ThreadState
    (此时将返回
    stopped
    )来检查线程的状态

    我们现在可以将线程的“内容”更改为

            happyThread.newStuff( ShortTest());
            happyThread.StartAgain();
    
    happyThread.newStuff( ShortTest());
    happyThread.StartAgain();
    
    不可以。不能将新函数绑定到已终止的线程,如果再次尝试调用
    happyThread.Start()
    ,它将抛出一个已启动的
    线程。

    我会仅仅在另一个新线程上再次开始短测试吗

    是的。您必须在
    新线程(ShortTest)
    上启动
    ShortTest
    (或者您可以将它添加到
    LongTest()
    方法的末尾。在线程上启动的任何新方法都将在该线程上运行)。但是,您可以在旧的
    happyThread
    上调用新线程。因此
    happyThread=新线程(ShortTest())
    将很高兴再次启动!在第一个线程用完之前,您甚至可以在
    happyThread
    上启动一个新线程。因此

    Thread happyThread = new Thread(LongTest());//say this runs for 1 minute
    happyThread.Start();
    happyThread = new Thread(ShortTest());//this will start without a problem
    happyThread.Start();
    
    也会很高兴地开始。但是请注意,这实际上不应该这样做。它会使您丢失对运行最长时间的线程的引用。(尽管先调用
    LongTest
    ShortTest
    ,但如果该线程恰好首先触发,那么实际上可能会首先开始运行……这确实远不理想,但只是想表明这是可能的。)

    short_功能是否也会在以后访问该值

    是的,我们假设
    int k
    是公共的和全局的,并且只在主线程上运行。您可以将其值从
    long\u function
    设置为42,然后如果需要,可以在不同的线程上从
    short\u function
    读取
    int k
    的值。现在请注意,在设置/获取多个变量时必须小心我用线来防止它

    但是,如果在单独线程上运行的方法中定义
    int k
    ,则当线程终止时,它将超出范围,就像函数终止时在函数内部初始化的任何变量一样

    您可以使用
    volatile
    关键字指示变量可能被多个线程修改

    如果你不得不启动无数的小任务

    如果要启动/关闭大量线程,您可能需要使用

    你能“重复使用”一个线程吗?你能再次“进入”它吗

    所以这一切都归结为否。一旦一个线程死亡,它就无法再次启动,请参阅该特定主题

    但是,作为替代方法,您可以在应用程序期间保持线程的活动状态,前提是您知道您将多次甚至连续地调用线程(例如,我使用此方法在后台保持TCP连接,该连接需要始终可访问)。可以这样做:

    Void Start()
    {
        Thread happyThread = new thread(() => KeepAlivethread(1000));//short, easy way to create a delegate so you can pass parameters to your thread aswell!
        happyThread.Start();
    }
    
    volatile bool keepThreadAlive = true;//volatile because it may be accessed from another thread
    
    private void KeepAliveThread(int timeout)
    {
        Debug.Log("Thread started with id: " + Thread.CurrentThread.ManagedThreadId); 
        while (keepThreadAlive)
        {
            //do something, maybe have an event that calls to ShortTest.
            Thread.Sleep(timeout);
        }
        Debug.Log("Thread terminating with id: " + Thread.CurrentThread.ManagedThreadId);
    }
    

    现在,此线程将在后台继续运行,直到您设置
    keepThreadAlive=false
    ,然后它将优雅地终止。(这样做,您就不必
    thread.Abort()
    ,这是不好的!(更多信息请参见前面链接的so帖子的答案)

    ThreadPool?…这很奇怪,出于某种原因,答案发布了两次……但第二次只是部分发布……有时发生在糟糕的互联网连接上;)保持住!@remy_rm让我们转到它说的地方:“当线程死了,可怜的k也死了。”k是一个全局的(注意,我编辑了这个问题,并显示了k在C源代码中声明的位置)..这肯定是不对的,k仍然存在,当线程正确死亡时设置为42??(是的,我