提交 a88acdbd 编写于 作者: cdy816's avatar cdy816

增加将线程指定到CPU,未完成

上级 944ae3d5
//==============================================================
// Copyright (C) 2020 Inc. All rights reserved.
//
//==============================================================
// Create by 种道洋 at 2020/7/20 13:44:40.
// Version 1.0
// 种道洋
//==============================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
namespace Cdy.Tag
{
/// <summary>
///
/// </summary>
public class ThreadHelper
{
#region ... Variables ...
#endregion ...Variables...
#region ... Events ...
#endregion ...Events...
#region ... Constructor...
#endregion ...Constructor...
#region ... Properties ...
#endregion ...Properties...
#region ... Methods ...
/// <summary>
/// CPU 个数
/// </summary>
/// <returns></returns>
public static int CPUNumbers()
{
return Environment.ProcessorCount;
}
/// <summary>
///
/// </summary>
/// <param name="cpus"></param>
public static void AssignToCPU(params int[] cpus)
{
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
SetThreadAffinityMaskWindows((UIntPtr)MaskFromIds(cpus));
}
else if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
}
else
{
//to do none;
}
}
/// <summary>
/// Sets a processor affinity mask for the current thread.
/// </summary>
/// <param name="mask">
/// A thread affinity mask where each bit set to 1 specifies a logical processor on which this thread is allowed to
/// run.
/// <remarks>Note: a thread cannot specify a broader set of CPUs than those specified in the process affinity mask.</remarks>
/// </param>
/// <returns>
/// The previous affinity mask for the current thread.
/// </returns>
/// <exception cref="Win32Exception"></exception>
public static UIntPtr SetThreadAffinityMaskWindows(UIntPtr mask)
{
var threadAffinityMask = Win32Native.SetThreadAffinityMask(Win32Native.GetCurrentThread(), mask);
if (threadAffinityMask == UIntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
return threadAffinityMask;
//return SetThreadAffinityMask(Win32Native.GetCurrentThread(), mask);
}
/// <summary>
/// Masks from ids.
/// </summary>
/// <param name="ids">The ids.</param>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException">CPUId</exception>
private static ulong MaskFromIds(IEnumerable<int> ids)
{
ulong mask = 0;
foreach (var id in ids)
{
if (id < 0 || id >= Environment.ProcessorCount)
{
throw new ArgumentOutOfRangeException("CPUId", id.ToString());
}
mask |= 1UL << id;
}
return mask;
}
/// <summary>
/// Ids from mask.
/// </summary>
/// <param name="mask">The mask.</param>
/// <returns></returns>
private static IEnumerable<int> IdsFromMask(ulong mask)
{
var ids = new List<int>();
var i = 0;
while (mask > 0UL)
{
if ((mask & 1UL) != 0)
{
ids.Add(i);
}
mask >>= 1;
i++;
}
return ids;
}
#endregion ...Methods...
#region ... Interfaces ...
#endregion ...Interfaces...
}
/// <summary>
/// Win32Native Class
/// </summary>
public static class Win32Native
{
/// <summary>
/// The kernel32
/// </summary>
private const string Kernel32 = "kernel32.dll";
/// <summary>
/// The NTDLL
/// </summary>
private const string Ntdll = "ntdll.dll";
/// <summary>
/// The psapi
/// </summary>
private const string Psapi = "psapi.dll";
/// <summary>
/// Enums the processes.
/// </summary>
/// <param name="processIds">The process ids.</param>
/// <param name="size">The size.</param>
/// <param name="needed">The needed.</param>
/// <returns></returns>
[DllImport(Psapi, CharSet = CharSet.Auto, SetLastError = true)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool EnumProcesses(int[] processIds, int size, out int needed);
/// <summary>
/// Opens the process.
/// </summary>
/// <param name="access">The access.</param>
/// <param name="inherit">if set to <c>true</c> [inherit].</param>
/// <param name="processId">The process identifier.</param>
/// <returns></returns>
[DllImport(Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern IntPtr OpenProcess(int access, bool inherit, int processId);
/// <summary>
/// Sets the thread affinity mask.
/// </summary>
/// <param name="handle">The handle.</param>
/// <param name="mask">The mask.</param>
/// <returns></returns>
[DllImport(Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
[ResourceExposure(ResourceScope.Process)]
internal static extern IntPtr SetThreadAffinityMask(IntPtr handle, HandleRef mask);
/// <summary>
/// Get current processor number.
/// </summary>
/// <returns></returns>
[DllImport(Ntdll, CharSet = CharSet.Auto)]
internal static extern uint NtGetCurrentProcessorNumber();
/// <summary>
/// Gets the current thread. GetCurrentThread() returns only a pseudo handle. No need for a SafeHandle here.
/// </summary>
/// <returns></returns>
[DllImport(Kernel32)]
internal static extern IntPtr GetCurrentThread();
/// <summary>
/// Sets the thread affinity mask.
/// </summary>
/// <param name="handle">The handle.</param>
/// <param name="mask">The mask.</param>
/// <returns></returns>
[DllImport(Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
internal static extern UIntPtr SetThreadAffinityMask(IntPtr handle, UIntPtr mask);
/// <summary>
/// Sets the process affinity mask.
/// </summary>
/// <param name="handle">The handle.</param>
/// <param name="mask">The mask.</param>
/// <returns></returns>
[DllImport(Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool SetProcessAffinityMask(IntPtr handle, IntPtr mask);
/// <summary>
/// Gets the process affinity mask.
/// </summary>
/// <param name="handle">The handle.</param>
/// <param name="processMask">The process mask.</param>
/// <param name="systemMask">The system mask.</param>
/// <returns></returns>
[DllImport(Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
[ResourceExposure(ResourceScope.None)]
internal static extern bool GetProcessAffinityMask(
IntPtr handle,
out IntPtr processMask,
out IntPtr systemMask);
}
}
......@@ -47,6 +47,8 @@ namespace Cdy.Tag
private long mTotalSize = 0;
public static List<int> UsedCPUs = new List<int>();
#endregion ...Variables...
#region ... Events ...
......@@ -201,6 +203,8 @@ namespace Cdy.Tag
resetEvent.Reset();
if (mIsClosed)
break;
ThreadHelper.AssignToCPU(UsedCPUs.ToArray());
//#if DEBUG
Stopwatch sw = new Stopwatch();
sw.Start();
......
......@@ -33,6 +33,8 @@ namespace Cdy.Tag
private Dictionary<int, long> dtmp = new Dictionary<int, long>();
private bool mIsDisposed=false;
private bool mIsRunning=false;
#endregion ...Variables...
#region ... Events ...
......
......@@ -52,6 +52,11 @@ namespace Cdy.Tag
private int mBusyCount = 0;
/// <summary>
///
/// </summary>
public static List<int> UsedCPUs = new List<int>();
#endregion ...Variables...
#region ... Events ...
......
......@@ -48,7 +48,9 @@ namespace Cdy.Tag
private Thread mRecordThread;
public static List<int> UsedCPUs = new List<int>();
#endregion ...Variables...
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册