如何避免C++;,VisualStudio(Windows) 我开发了一个记录器,用于测试C++、Win32控制台、VisualStudio(Windows)中的模块。 记录器正在一个线程中运行。 当它在控制台窗口中显示输出时,线程被抢占。 其他一些模块线程正在运行。 所以其他模块的输出和控制台窗口中记录器模块的输出混合在一起

如何避免C++;,VisualStudio(Windows) 我开发了一个记录器,用于测试C++、Win32控制台、VisualStudio(Windows)中的模块。 记录器正在一个线程中运行。 当它在控制台窗口中显示输出时,线程被抢占。 其他一些模块线程正在运行。 所以其他模块的输出和控制台窗口中记录器模块的输出混合在一起,c++,multithreading,C++,Multithreading,是否有任何方法可以避免记录器线程的抢占,以便整个记录器输出可以位于控制台输出窗口中的一个位置 写入文件而不是输出窗口是一种解决方案。但由于不同机器上的驱动器名称可能不同,因此很难对记录器输出文件路径进行硬编码。即使这样,我们仍然可以编写代码来查找任何机器上可用的驱动器,并写入第一个驱动器等。但测试人员可能不知道在哪里搜索记录器输出文件。将线程Id添加到记录器输出,然后使用可以进行筛选的日志查看器 (在windows下)允许您将突出显示筛选器添加到动态日志记录中。将线程Id添加到记录器输出中,然后

是否有任何方法可以避免记录器线程的抢占,以便整个记录器输出可以位于控制台输出窗口中的一个位置


写入文件而不是输出窗口是一种解决方案。但由于不同机器上的驱动器名称可能不同,因此很难对记录器输出文件路径进行硬编码。即使这样,我们仍然可以编写代码来查找任何机器上可用的驱动器,并写入第一个驱动器等。但测试人员可能不知道在哪里搜索记录器输出文件。

将线程Id添加到记录器输出,然后使用可以进行筛选的日志查看器


(在windows下)允许您将突出显示筛选器添加到动态日志记录中。

将线程Id添加到记录器输出中,然后使用可以进行筛选的日志查看器


(在windows下)允许您向动态日志添加突出显示过滤器。

防止线程抢占通常是危险的。您可以尝试暂时增加线程优先级,但我不建议这样做(危险;无法在多处理器上工作,…)

其他途径:

  • 重写所有模块,仅将记录器用于输出
  • 如果其他模块仅写入cout/stdout:记录器应写入cerr/stderr。这不会阻止控制台中的混合输出。但是当将程序输出重定向到不同的文件时,它会

    • 防止线程抢占通常是危险的。您可以尝试暂时增加线程优先级,但我不建议这样做(危险;无法在多处理器上工作,…)

      其他途径:

      • 重写所有模块,仅将记录器用于输出
      • 如果其他模块仅写入cout/stdout:记录器应写入cerr/stderr。这不会阻止控制台中的混合输出。但是当将程序输出重定向到不同的文件时,它会

        • 标准解决方案是使用互斥锁。格式化之后,但在开始向控制台输出之前,锁定互斥锁。发送所有输出后,将再次解锁互斥锁。如果第二个线程进入,其锁定互斥锁的尝试将导致该线程被抢占,直到第一个线程完成


          Windows中的CriticalSection的行为类似于互斥,也可用。它们使用的术语略有不同。您不需要“锁定”它们,而是使用
          EnterCriticalSection
          LeaveCriticalSection
          “进入”和“离开”关键部分。标准解决方案是使用互斥锁。格式化之后,但在开始向控制台输出之前,锁定互斥锁。发送所有输出后,将再次解锁互斥锁。如果第二个线程进入,其锁定互斥锁的尝试将导致该线程被抢占,直到第一个线程完成


          Windows中的CriticalSection的行为类似于互斥,也可用。它们使用的术语略有不同。您不需要“锁定”它们,而是使用
          EnterCriticalSection
          LeaveCriticalSection
          来“进入”和“离开”关键部分。我认为最好的解决方案是简单地将记录器输出与程序的其余输出分开。您提到了将日志写入文件的可能性。如果此解决方案的唯一障碍是编码适当的路径,则可以动态选择输出路径:

          TCHAR buffer[ MAX_PATH ];
          
          SHGetSpecialFolderPath( NULL, buffer, CSIDL_LOCAL_APPDATA, TRUE );
          

          这将为您提供当前用户的本地应用程序数据文件夹。然后,您可以添加日志文件名。

          我认为最好的解决方案是简单地将记录器输出与程序的其余输出分开。您提到了将日志写入文件的可能性。如果此解决方案的唯一障碍是编码适当的路径,则可以动态选择输出路径:

          TCHAR buffer[ MAX_PATH ];
          
          SHGetSpecialFolderPath( NULL, buffer, CSIDL_LOCAL_APPDATA, TRUE );
          

          这将为您提供当前用户的本地应用程序数据文件夹。然后,您可以添加日志文件名。

          是的,我可以使用日志查看器。但在调试时,输出将变得更加笨拙。所以那个时候,我不能过滤掉每个字符或单词的输出。是的,我可以使用日志查看器。但在调试时,输出将变得更加笨拙。那时候,我不能过滤每个字符或单词的输出。如果你想让你的日志记录原子化,那么你可以试着把日志数据放在一个字符串(或一个字符串流)中,然后,做一个
          cout这个现象与严格意义上的线程抢占无关。记录器线程和“其他一些模块线程”都可以在多核机器上同时运行。如果您想使日志记录原子化,那么您可以尝试将日志记录数据放入字符串(或StringStream)中,然后执行
          cout此现象与严格意义上的线程抢占无关。记录器线程和“其他一些模块线程”都可以在多核计算机上同时运行。嗨,我必须包括哪些头文件?包括“Shlobj.h”。您可以在此处找到此函数的MSDN文档:嗨,我必须包括哪些头文件?包括“Shlobj.h”您可以在此处找到此功能的MSDN文档: