首页 > 其他分享 >远程调试&线程检查&性能检查

远程调试&线程检查&性能检查

时间:2023-08-17 18:14:46浏览次数:37  
标签:Console Thread 检查 lock static 线程 调试

vs2022的一些调试技巧——远程调试&线程检查&性能检查

visual studio一直都是.net/c#开发人员最受欢迎的编译器,除了强大的代码提示和项目模板,还拥有大量的调试工具,这一期我们介绍下code freeze阶段的一些调试技巧。包括测试环境/生产环境下的远程调试,线程调试,以及性能监控调试。

 

目录

 

远程调试

当我们的程序所在的目标机器没有跑源码所需的sdk或者没办法安装vs的时候,我们需要对目标机器上正在运行或者即将运行的应用进行调试。我们通过远程调试在本机上对目标机器调试。

1 安装

Remote Debug下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/?rr=https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging?view=vs-2019
image
选择下载进行安装,最后管理员运行。
image
查看目标机运行所使用的端口号
image

2.调试

1.调试->附加进程
修改对应的目标主机的端口和IP地址
image

2.选中对应的进程点击附加
image

3.我们贴上一段代码,代码会死循环打印一个自增的数

static void Main(string[] args)
{
    int i = 0;
    while (true) 
    {
        Console.WriteLine(++i);
        Thread.Sleep(1000);
    }
}

我们在目标主机运行起来,然后在本地利用源码进行远程调试,并且加上一个断点。发现断点进来了,并且程序不再打印,则调试成功。
image

线程调试

我们可以利用visual studio的线程窗口来查看目前所有的活动线程的运行情况以及线程目前在代码何处运行。该功能配合远程调试可以很好的观察生产或者测试环境下的死锁问题。当然开发环境下也一样。

我们来调查一个死锁。
先实现一个简单的死锁程序:声明两个锁对象,并且用两个线程各自占用一个锁,再去索要另外一个锁,形成死锁。

private static object _lock = new object();
        private static object _lock_1 = new object();
        static void Main(string[] args)
        {
            var task1 = Task.Run(DeadLock);
            var task2 = Task.Run(DeadLock_1);

            Task.WaitAll(task1,task2);
            Console.WriteLine("Hello, World!");
        }

        private static void DeadLock()
        {
            lock (_lock)
            {
                Thread.Sleep(200);
                lock (_lock_1)
                {
                    Console.WriteLine("DeadLock");
                }
            }
        }

        private static void DeadLock_1()
        {
            lock (_lock_1)
            {
                Thread.Sleep(200);
                lock (_lock)
                {
                    Console.WriteLine("DeadLock_1");
                }
            }
        }

运行程序之后,将程序中断
image
点击调试->窗口->线程
可以看到两个工作线程,双击可以查看该线程中断时所处的位置。从而可以分析线程是否阻塞在这里,是否是形成问题的关键。
image

image

性能调试

VS自带的性能监控工具提供了一些数据的监控和分析,比较常用的就是CPU使用和内存IO的监控。它支持本地启动项目的监控以及进程和可执行程序的附加。

点击调试->性能追踪(Performance Profiler)
image

我们来实现一个CPU密集型的代码

        static async Task Main(string[] args)
        {
            await MultiRunning();
            SomeThing();
            Console.WriteLine("Hello, World!");
        }

        //启动20个线程
        static async Task MultiRunning()
        {
            Thread[] tasks = new Thread[20];
            foreach (var index in Enumerable.Range(0, tasks.Length))
            {
                tasks[index] = new Thread(() =>
                {
                    while (true)
                    {
                        int a = 1;
                        Thread.Sleep(200);
                    }
                });
            }

            int i = 0;
            await Parallel.ForEachAsync(tasks, (task, source) =>
            {
                i++;
                task.Start();
                return ValueTask.CompletedTask;
            });

            Console.WriteLine("执行了" + i);
        }

        static void SomeThing()
        {
            while (true)
            {
                Console.WriteLine("I AM Alive");
                Thread.Sleep(200);
            }
        }

我们使用Performance Profiler对启动项目的CPU进行监控。
image
image
当我们觉得程序运行的差不多了,我们可以点击停止搜集,然后visual studio会给我们生成一些分析数据
image
点击打开详情,然后根据函数来分析占用的CPU,默认也是按照函数所占用的CPU时间片来进行排序。选择我们程序的函数,双击Main函数,可以看到里面的方法各自的占用,从而判断找出高CPU的函数。
image

以此类推,如果需要寻找高IO的根源点,也可以使用VS自带的Performace Profiler来追踪代码的执行性能。

标签:Console,Thread,检查,lock,static,线程,调试
From: https://www.cnblogs.com/Leo_wl/p/17638389.html

相关文章

  • 在C++中实现多线程异步TCP消息发送
    本文主要解释了在C++中如何实现一个多线程,异步发送TCP消息的系统。我们将会用到C++的标准库和Boost.Asio库。基础知识TCP(TransmissionControlProtocol):是一种面向连接的、可靠的、基于字节流的通信协议。它在两个网络节点之间创建一个稳定的连接,以便可以交换字节流。多线程编程:......
  • 进程 线程
    个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过程中与进程还是有区别的。 每个独立的线程有一个程序运行的入口、......
  • JAVA SSH 连接服务器 去指定目录 检查文件 并读取json文件内容
    要使用JavaSSH连接服务器并检查文件,可以使用JSch库。以下是一个示例代码:importcom.jcraft.jsch.*;​importjava.io.BufferedReader;importjava.io.InputStream;importjava.io.InputStreamReader;​publicclassSSHExample{publicstaticvoidmain(String[]ar......
  • 爬虫速度翻倍!多线程技术助你提升批量爬虫采集效率
       今天要和大家分享一些关于如何利用多线程技术提升批量爬虫采集效率的实用技巧。如果你也在面对大量数据采集任务的时候疲于奔命,那么这些经验对你来说将非常有帮助。废话不多说,让我们开始吧!1.多线程是什么?——理解多线程的概念多线程是指在一个程序中同时运行多个......
  • keil程序调试,malloc 不成功
    what程序里申请了,300k空间,但是malloc返回值一直是NULLwhymalloc申请的是堆空间,系统启动.S文件中设置的堆空间大小最多8k,申请的空间大小超过了实际空间大小,故申请失败 KEIL使用malloc函数申请堆空间失败的解决方法_keilmalloc失败_小刘同学啊的博客-CSDN博客......
  • SDL 线程创建(SDL_LockMutex / SDL_UnlockMutex、SDL_CondWait / SDL_CondSignal)
     SDL_mutex*s_lock=NULL;SDL_cond*s_cond=NULL;intthread_work(void*arg){ SDL_LockMutex(s_lock); printf("[thread_work]in.\n"); Sleep(5000); printf("[thread_work]好了,知道了,我刚刚去玩了5秒,我直接SDL_CondWait把锁给你我自己睡觉去了。你拿到锁......
  • 工作中怎么使用线程池
    8个Java线程池最佳实践和坑! 1、正确声明线程池线程池必须手动通过 ThreadPoolExecutor 的构造函数来声明,避免使用Executors 类创建线程池,会有OOM风险。Executors 返回线程池对象的弊端如下(后文会详细介绍到):FixedThreadPool 和 SingleThreadExe......
  • 线程安全的集合
    Java的集合框架提供了许多集合类,其中有些是线程安全的,有些是非线程安全的。以下是一些线程安全的集合类:1.Vector:Vector是线程安全的动态数组类,与ArrayList类似,但它是同步的。2.Stack:Stack类是Vector的一个子类,它实现了一个后进先出的堆栈。3.Hashtable:Hashtable是一......
  • 多线程的“锁”
    其实,很多初学者(包括我自己)初期学习多线程时都被视频带偏了...虽然我始终认为培训班的视频是最适合非科班零基础入门的,但是在多线程方面,无一例外都讲得比较糟糕。感触很深的一点是:很多新手觉得多线程难,并不是因为volatile、ReentrantLock或者Executor线程池,而是从一开始就没弄明白......
  • qt 线程
    qt线程创建有两种方式:1、信号槽形式2、继承QThread形式。这里记一下信号槽形式。参考:https://blog.csdn.net/douzhq/article/details/104156580worker.h1#ifndefWORKER_H2#defineWORKER_H34#include<QObject>5classWorker:publicQObject6{7Q......