Skip to content

Instantly share code, notes, and snippets.

@lazalong
Created February 6, 2021 07:38
Show Gist options
  • Save lazalong/241a34bef0b04a0c0a8cf428958e869b to your computer and use it in GitHub Desktop.
Save lazalong/241a34bef0b04a0c0a8cf428958e869b to your computer and use it in GitHub Desktop.
/*
* C# Thread Helper
* Copyright (c) 2021 Steven 'lazalong' Gay
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
namespace NetServer
{
public static class ThreadHelper
{
[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();
static readonly Process _currentProcess = null;
static ThreadHelper()
{
if (_currentProcess == null)
_currentProcess = Process.GetCurrentProcess();
}
// Can be used as offset for subsequent created threads
public static int GetNbThreads()
{
_currentProcess.Refresh();
return _currentProcess.Threads.Count;
}
public static int GetNbLogicalCores()
{
return Environment.ProcessorCount;
}
// Set the affinity of a thread
// Bind the thread to the 'processNb' process [1-8] in a 8 cores machine
// process.Threads[i + offset].ProcessorAffinity = (IntPtr)(1L << i);
public static void SetAffinity(int threadIndex, int processIndex)
{
Assert.Check(processIndex >= 0 && processIndex <= Environment.ProcessorCount);
#pragma warning disable CA1416
_currentProcess.Threads[threadIndex].IdealProcessor = processIndex;
if (processIndex == 0)
_currentProcess.Threads[threadIndex].ProcessorAffinity = (IntPtr)(1);
else
_currentProcess.Threads[threadIndex].ProcessorAffinity = (IntPtr)(1L << processIndex);
#pragma warning restore CA1416
}
public static int GetThreadIndex(int id)
{
int nb = GetNbThreads();
for (int i = 0; i < nb; i++)
{
if (_currentProcess.Threads[i].Id == id)
return i;
}
return -1;
}
public static ProcessThread CurrentThread
{
get
{
int id = GetCurrentThreadId();
return
(from ProcessThread th in Process.GetCurrentProcess().Threads
where th.Id == id
select th).Single();
}
}
public static void PrintAllThreads(int max = 10)
{
int nb = GetNbThreads();
if (nb > max) nb = max;
Console.WriteLine("Threads:");
for (int i = 0; i < nb; i++)
{
Console.WriteLine($" {i} : {_currentProcess.Threads[i].Id}");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment