あさまのブログ

SEをやってます。覚えたことなんかを書いていきます。

【.NET C#】動作するCPU(プロセッサー)を指定してアプリを起動させる。その1

仕事が色々立て込みまして、かなり久しぶりの更新になってしまいました。

今回は動作するCPUのコアを指定して、他のプロセスを起動するアプリを作成してみようと思います。

まず使用しているCPUのコア数を確認。 Win8 or 10なら「Winキー+Q」のアプリ検索で「システム情報」と入力して下記画面を表示して確認。 コア数4のスレッド数8のようです。 f:id:maasasa:20170701002053p:plain

.NET標準のProcessクラスで簡単にできる、、、! Win32とか使うと思ってたので用意してくれていると助かります。
ProcessThread.ProcessorAffinity プロパティ (System.Diagnostics)

今回は親プロセス(起動指示を出すアプリ)にCPU1、 子プロセスAにCPU2、子プロセスBにCPU3を割り当てようと思います。

WPFで作成しました。(コードビハインドですみません)

まず親プロセス

MainWindow.xaml

<Window x:Class="ProcessStartupApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ProcessStartupApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="158.824" Width="325">
    <Grid>
        <Label Content="動作プロセッサ設定値は" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <Label Name="TargetProcessor" Content="x" HorizontalAlignment="Left" Margin="167,10,0,0" VerticalAlignment="Top" RenderTransformOrigin="2.695,0.538"/>
        <Label Content="です" HorizontalAlignment="Left" Margin="196,10,0,0" VerticalAlignment="Top" RenderTransformOrigin="2.695,0.538"/>
        <Button Name="Button1" Click="Button1_Click" Content="プロセスA起動" HorizontalAlignment="Left" Margin="10,70,0,0" VerticalAlignment="Top" Width="80"/>
        <Button Name="Button2" Click="Button2_Click" Content="プロセスB起動" HorizontalAlignment="Left" Margin="109,70,0,0" VerticalAlignment="Top" Width="80"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Diagnostics;
using System.Windows;

namespace ProcessStartupApp {
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            //自身をCPU1で動作させる。
            Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)1;
            //自身の動作CPUを取得する。
            var processor = Process.GetCurrentProcess().ProcessorAffinity.ToInt32();
            this.TargetProcessor.Content = processor.ToString();
        }

        private void Button1_Click(object sender, RoutedEventArgs e) {
            var path = @"..\..\..\ProcessA\bin\Debug\ProcessA.exe";
            var processor = 2;
            //CPU2を指定して起動する。
            bootingProcess(path, processor);
        }

        private void Button2_Click(object sender, RoutedEventArgs e) {
            var path = @"..\..\..\ProcessB\bin\Debug\ProcessB.exe";
            //プロパティ値に3を指定すると、1または2のCPUを使用する。
            var processor = 4;
            //CPU3を指定して起動する。
            bootingProcess(path, processor);
        }

        private bool bootingProcess(string path, int processor) {
            try {
                using (Process p = new Process()) {
                    p.StartInfo.FileName = path;
                    var isBoot = p.Start();
                    //動作するCPUを指定
                    p.ProcessorAffinity = (IntPtr)processor;
                    return isBoot;
                }
            } catch {
                return false;
            }
        }
    }
}

次に子プロセスを別プロジェクトで作成します。 記事が長くなってきたので次の記事に分割します。
maasasa.hatenablog.com