C#控制线程(恢复/挂起) [英] C# controlling threads (resume/suspend)

查看:639
本文介绍了C#控制线程(恢复/挂起)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试模拟(非常简单)的OS进程管理器子系统,我有3个进程"(工作人员)在控制台上编写内容(这是一个示例):

I'm trying to simulate (very basic & simple) OS process manager subsystem, I have three "processes" (workers) writing something to console (this is an example):

    public class Message
    {
        public Message() { }
        public void Show()
        {
            while (true)
            {
                Console.WriteLine("Something");
                Thread.Sleep(100);
            }
        }
    }

每个工作程序应该在不同的线程上运行.我现在就是这样做的: 我有一个Process类,该类的构造函数接受Action委托,并从中启动一个线程,并暂停它.

Each worker is supposed to be run on a different thread. That's how I do it now: I have a Process class which constructor takes Action delegate and starts a thread from it and suspends it.

public class Process
{
    Thread thrd;
    Action act;

    public Process(Action act)
    {
        this.act = act;

        thrd = new Thread(new ThreadStart(this.act));
        thrd.Start();
        thrd.Suspend();
    }

    public void Suspend()
    {
        thrd.Suspend();
    }

    public void Resume()
    {
        thrd.Resume();
    }
}

在这种状态下,它等待我的调度程序恢复它,给它一个时间片运行,然后再次挂起它.

In that state it waits before my scheduler resumes it, gives it a time slice to run, then suspends it again.

        public void Scheduler()
        {
            while (true)
            {
                //ProcessQueue is just FIFO queue for processes
                //MainQueue is FIFO queue for ProcessQueue's
                ProcessQueue currentQueue = mainQueue.Dequeue();
                int count = currentQueue.Count;

                if (currentQueue.Count > 0)
                {
                    while (count > 0)
                    {
                        Process currentProcess = currentQueue.GetNext();

                        currentProcess.Resume();
                        //this is the time slice given to the process
                        Thread.Sleep(1000);
                        currentProcess.Suspend();

                        Console.WriteLine();
                        currentQueue.Add(currentProcess);

                        count--;
                    }
                }

                mainQueue.Enqueue(currentQueue);
            }
        }

问题在于它不能始终如一地工作.在这种状态下,它甚至根本无法工作,我必须像这样在工作人员的Show()方法的WriteLine之前添加Thread.Sleep().

The problem is that it doesn't work consistently. It even doesn't work at all in this state, i have to add Thread.Sleep() before WriteLine in Show() method of the worker, like this.

        public void Show()
        {
            while (true)
            {
                Thread.Sleep(100); //Without this line code doesn't work
                Console.WriteLine("Something");
                Thread.Sleep(100);
            }
        }

我一直在尝试使用ManualResetEvent而不是suspend/resume,但是它可以共享,但是由于该事件是共享的,因此依赖于该事件的所有线程会同时唤醒,而我一次只需要一个特定的线程就可以活动.

I've been trying to use ManualResetEvent instead of suspend/resume, it works, but since that event is shared, all threads relying on it wake up simultaneously, while I need only one specific thread to be active at one time.

如果有人可以帮助我弄清楚如何正常地暂停/恢复任务/线程,那就太好了. 我正在做的是尝试模拟简单的抢先式多任务处理. 谢谢.

If some could help me figure out how to pause/resume task/thread normally, that'd be great. What I'm doing is trying to simulate simple preemptive multitasking. Thanks.

推荐答案

Thread.Suspend是邪恶的.它与Thread.Abort一样邪恶.在任意,不可预测的位置暂停时,几乎没有代码是安全的.它可能持有一个导致其他线程也暂停的锁.您很快会在系统的其他部分遇到死锁或无法预测的停顿.

Thread.Suspend is evil. It is about as evil as Thread.Abort. Almost no code is safe in the presence of being paused at arbitrary, unpredictable locations. It might hold a lock that causes other threads to pause as well. You quickly run into deadlocks or unpredictable stalls in other parts of the system.

想象一下,您不小心暂停了string的静态构造函数.现在,所有要使用string的代码也都停止了. Regex在内部使用锁定的缓存.如果在获取此锁期间暂停,则所有与Regex相关的代码都可能暂停.这只是两个令人震惊的例子.

Imagine you were accidentally pausing the static constructor of string. Now all code that wants to use a string is halted as well. Regex internally uses a locked cache. If you pause while this lock is taken all Regex related code might pause. These are just two egregious examples.

可能,在Console类内部深处暂停一些代码会带来意想不到的后果.

Probably, suspending some code deep inside the Console class is having unintended consequences.

我不确定该向您推荐什么.这似乎是一项学术活动,所以值得庆幸的是,这对您来说不是一个生产问题.在实践中,用户模式的等待和取消必须是协作的.

I'm not sure what to recommend to you. This seems to be an academic exercise so thankfully this is not a production problem for you. User-mode waiting and cancellation must be cooperative in practice.

这篇关于C#控制线程(恢复/挂起)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆