为什么进程会丢失线程?

发布于 2024-11-19 04:47:49 字数 1889 浏览 2 评论 0原文

下面是一些永久生成 GUID 的代码。我写它是为了了解线程。在其中您会注意到,即使 ConcurrentQueue 是线程安全的,我也锁定了生成 GUID 并将其排入队列的位置。这是因为我的实际代码需要使用 NHibernate,所以我必须确保只有一个线程填充队列。

当我在任务管理器中监视此代码时,我注意到该进程的线程数从 18 个(在我的计算机上)减少到 14 个,但不少于。这是因为我的代码不好吗?

如果他们认为合适的话,有人可以重构这个吗?我喜欢较短的代码。

class Program
{
    ConcurrentNewsBreaker Breaker;

    static void Main(string[] args)
    {
        new Program().Execute();

        Console.Read();
    }

    public void Execute()
    {
        Breaker = new ConcurrentNewsBreaker();
        QueueSome();
    }

    public void QueueSome()
    {
        ThreadPool.QueueUserWorkItem(DoExecute);
    }

    public void DoExecute(Object State)
    {
        String Id = Breaker.Pop();
        Console.WriteLine(String.Format("- {0} {1}", Thread.CurrentThread.ManagedThreadId, Breaker.Pop()));

        if (Breaker.Any())
            QueueSome();
        else
            Console.WriteLine(String.Format("- {0} XXXX ", Thread.CurrentThread.ManagedThreadId));            
    }
}


public class ConcurrentNewsBreaker
{
    static readonly Object LockObject = new Object();

    ConcurrentQueue<String> Store = new ConcurrentQueue<String>();

    public String Pop()
    {
        String Result = null;
        if (Any())
            Store.TryDequeue(out Result);
        return Result;
    }

    public Boolean Any()
    {
        if (!Store.Any())
        {
            Task FillTask = new Task(FillupTheQueue, Store);
            FillTask.Start();
            FillTask.Wait();
        }

        return Store.Any();
    }

    private void FillupTheQueue(Object StoreObject)
    {
        ConcurrentQueue<String> Store = StoreObject as ConcurrentQueue<String>;
        lock(LockObject)
        {
            for(Int32 i = 0; i < 100; i++)
                Store.Enqueue(Guid.NewGuid().ToString());            
        }
    }
}

Here is some code that perpetually generate GUIDs. I've written it to learn about threading. In it you'll notice that I've got a lock around where I generate GUIDs and enqueue them even though the ConcurrentQueue is thread safe. It's because my actual code will need to use NHibernate and so I must make sure that only one thread gets to fill the queue.

While I monitor this code in Task Manager, I notice the process drops the number of threads from 18 (on my machine) to 14 but no less. Is this because my code isn't good?

Also can someone refactor this if they see fit? I love shorter code.

class Program
{
    ConcurrentNewsBreaker Breaker;

    static void Main(string[] args)
    {
        new Program().Execute();

        Console.Read();
    }

    public void Execute()
    {
        Breaker = new ConcurrentNewsBreaker();
        QueueSome();
    }

    public void QueueSome()
    {
        ThreadPool.QueueUserWorkItem(DoExecute);
    }

    public void DoExecute(Object State)
    {
        String Id = Breaker.Pop();
        Console.WriteLine(String.Format("- {0} {1}", Thread.CurrentThread.ManagedThreadId, Breaker.Pop()));

        if (Breaker.Any())
            QueueSome();
        else
            Console.WriteLine(String.Format("- {0} XXXX ", Thread.CurrentThread.ManagedThreadId));            
    }
}


public class ConcurrentNewsBreaker
{
    static readonly Object LockObject = new Object();

    ConcurrentQueue<String> Store = new ConcurrentQueue<String>();

    public String Pop()
    {
        String Result = null;
        if (Any())
            Store.TryDequeue(out Result);
        return Result;
    }

    public Boolean Any()
    {
        if (!Store.Any())
        {
            Task FillTask = new Task(FillupTheQueue, Store);
            FillTask.Start();
            FillTask.Wait();
        }

        return Store.Any();
    }

    private void FillupTheQueue(Object StoreObject)
    {
        ConcurrentQueue<String> Store = StoreObject as ConcurrentQueue<String>;
        lock(LockObject)
        {
            for(Int32 i = 0; i < 100; i++)
                Store.Enqueue(Guid.NewGuid().ToString());            
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

追我者格杀勿论 2024-11-26 04:47:49

您正在使用.NET 的ThreadPool,因此.NET/Windows 根据等待处理的工作量来管理线程数。

You are using .NET's ThreadPool so .NET/Windows manages the number of threads based on the amount of work waiting to be processed.

小清晰的声音 2024-11-26 04:47:49

当我在任务中监视此代码时
经理,我注意到进程下降了
线程数从 18 开始(在我的
机)到 14 但不少于。这是
因为我的代码不好?

这并不表示有问题。 14 仍然很高,除非你有 16 核 cpu。

线程池将尝试调整并使用尽可能少的线程来完成工作。

当线程数量显着增加时,您应该开始担心。

While I monitor this code in Task
Manager, I notice the process drops
the number of threads from 18 (on my
machine) to 14 but no less. Is this
because my code isn't good?

This does not indicate a problem. 14 is still high, unless you've got a 16-core cpu.

The threadpool will try to adjust and do the work with as few threads as possible.

You should start to worry when the number of threads goes up significantly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文