Upgrade to Pro — share decks privately, control downloads, hide ads and more …

C#-マルチコアプログラミングへの手引き-

 C#-マルチコアプログラミングへの手引き-

Es_Program

May 15, 2018
Tweet

More Decks by Es_Program

Other Decks in Technology

Transcript

  1. ThreadΫϥεͷجຊ ͜ͷํ๏͚͕ͩεϨουϓʔϧΛ࢖Θͳ͍ Thread t = new Thread(new ThreadStart(ॲཧ));ͱ͍͏ײ͡ͰεϨουΛ࡞Δ t.Start();ͰεϨου։࢝ t.Join();ͰεϨουͷ׬ྃ·ͰݱࡏͷεϨουΛࢭΊΔ

    t.Abort();ͰॲཧΛଧͪ੾Δ(ThreadAbortExceptionΛൃੜͤ͞Δ) IsBackgroundͰϑΥΞ/όοΫάϥ΢ϯυΛมߋՄೳ IsBackgroundͷنఆ஋͸falseͰϑΥΞάϥ΢ϯυεϨου
  2. TaskΛ࢖͏ Task t = new Task(ॲཧ); t.Start();͜ΕͰॲཧΛελʔτग़དྷΔ Task t =

    Task.Run(ॲཧ);্2ߦΛ·ͱΊΒΕΔ Task t = new Task.Factory.StartNew(ॲཧ,Φϓγϣϯ);ͰΦϓγϣϯΛࢦఆͯ͠λεΫ Λ࡞੒࣮͠ߦͰ͖Δ t.IsCompletedͰॲཧ͕׬͔ྃͨ͠Ͳ͏͔ௐ΂ΒΕΔ(ϙʔϦϯάͰ࢖͑Δ) t.Wait();ͰλεΫͷॲཧऴྃΛ଴ػͰ͖Δ Task.WaitAll(Մม௕ͰλεΫΛࢦఆ);੩తϝιουͰࢦఆͨ͠λεΫશͯͷऴྃΛ଴ػ Ͱ͖Δ
  3. Task ໭Γ஋Λαϙʔτ͍ͯ͠Δ TaskΫϥεͷδΣωϦοΫ൛ʹฦ͍ͨ͠Ҿ਺Λࢦఆͯ͠TaskΛ࡞੒ ͠࢖͏ Task<int> t = new Task<int>(ॲཧ); t.Start();

    int result = t.Result; ResultϓϩύςΟΛ࢖༻ͨ࣌͠఺Ͱɺݺͼग़͠ଆͷεϨου͸݁Ռ ͕ฦͬͯ͘Δ·Ͱ଴ػ͢Δ
  4. using System;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.Remoting.Messaging;
 
 namespace

    ConsoleProject
 {
 class MainClass
 {
 public static void Main(string[] args)
 {
 Thread t = new Thread(new ThreadStart(Show));
 t.Start();
 Console.WriteLine("Main Method called.");
 t.Join();
 Console.WriteLine("exit...");
 }
 
 public static void Show()
 {
 Thread.Sleep(100);
 Console.WriteLine("Show Method called.");
 }
 }
 }

  5. using System;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.Remoting.Messaging;
 
 namespace

    ConsoleProject
 {
 class MainClass
 {
 static int x = 100;
 
 public static void Main(string[] args)
 {
 //2ͭͷεϨουͰڞ௨ͷϑΟʔϧυ(ࢿݯ)Λར༻͢Δ
 Thread t1 = new Thread(new ThreadStart(ShowAndIncrement));
 t1.Start();
 Thread t2 = new Thread(new ThreadStart(Show));
 t2.Start();
 
 //ऴྃ଴ͪ
 t1.Join();
 t2.Join();
 Console.WriteLine("exit...");
 }
 
 public static void ShowAndIncrement()
 {
 Thread.Sleep(100);
 Console.WriteLine("ShowAndIncrement Method called. ref value = { 0}", x++);
 }
 
 public static void Show()
 {
 Console.WriteLine("Show Method called. ref value = { 0}", x);
 }
 }
 } ShowAndIncrement͸͕࣌ؒ ͔͔ΔॲཧͳͷͰɺ͜ΕͰ͸ ࢥ͏Α͏ͳॱ൪Ͱ࣮ߦ͞Εͳ͍ Thread͸໭Γ஋Λαϙʔτ͍ͯ͠ͳ͍ͷͰ ϑΟʔϧυΛ࢖ͬͯڞ༗͢Δ ThreadStart͸Ҿ਺΋ αϙʔτ͞Εͯͳ͍
  6. using System;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.Remoting.Messaging;
 
 namespace

    ConsoleProject
 {
 class MainClass
 {
 static int x = 100;
 
 public static void Main(string[] args)
 {
 //2ͭͷεϨουͰڞ௨ͷϑΟʔϧυ(ࢿݯ)Λར༻͢Δ
 Thread t1 = new Thread(new ThreadStart(ShowAndIncrement));
 t1.Start();
 t1.Join();//ऴྃΛ଴ͭ
 Thread t2 = new Thread(new ThreadStart(Show));
 t2.Start();
 
 //ऴྃ଴ͪ
 t2.Join();
 Console.WriteLine("exit...");
 }
 
 public static void ShowAndIncrement()
 {
 Thread.Sleep(100);
 Console.WriteLine("ShowAndIncrement Method called. ref value = { 0}", x++);
 }
 
 public static void Show()
 {
 Console.WriteLine("Show Method called. ref value = { 0}", x);
 }
 }
 } ͜ΕͳΒ͏·͍͕͘͘ JoinͰॲཧΛ଴ͭ࣌ؒ ͕ඞཁʹͳΔ
  7. using System;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.Remoting.Messaging;
 
 namespace

    ConsoleProject
 {
 class MainClass
 {
 //ϙʔϦϯά͢ΔͨΊͷ࢓ֻ͚
 static bool endFunc = false;
 
 public static void Main(string[] args)
 {
 int x = 100;
 //Ωϡʔʹ഑ஔग़དྷͳ͔ͬͨ৔߹ʹfalse͕ฦͬͯ͘Δ͕΄΅ແҙຯͳͷͰී௨͸औಘ͠ͳͯ͘΋͍͍
 //ԿނͳΒɺ഑ஔग़དྷͳ͔ͬͨ৔߹͸ྫ֎͕ૹग़͞ΕΔ͔Β
 bool qurResult = ThreadPool.QueueUserWorkItem(new WaitCallback(Show), x);
 //εϨουϓʔϧͷॲཧ͕ऴ͔ྃͨ͠Λ൑ఆ͢Δ࢓ֻ͚͸ඪ४Ͱ͸༻ҙ͞Ε͍ͯͳ͍
 //ඞཁͳΒϙʔϦϯά͢Δ࢓ֻ͚Λࣗ෼Ͱ༻ҙ͢Δ
 while (!endFunc)
 {
 //ॲཧ͕ऴΔ·ͰϙʔϦϯά
 }
 Console.WriteLine("exit...");
 }
 
 public static void Show(object x)
 {
 Console.WriteLine(x);
 Thread.Sleep(2000);//2ඵ͔͔Δॲཧ
 endFunc = true;
 }
 }
 } ීஈ͸QueueUserWorkItem ͷ໭Γ஋͸ࣺͯͯΑ͍ ϙʔϦϯάͷखஈ͕༻ҙ ͞Ε͍ͯͳ͍ͨΊࣗ෼Ͱ ࣮૷͢Δඞཁ͕͋Δ WaitCallbackσϦήʔτͷ γάωνϟʹैͬͨϝιου
  8. using System;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.Remoting.Messaging;
 
 namespace

    ConsoleProject
 {
 class MainClass
 {
 public static void Main(string[] args)
 {
 Action<int> act;
 act = n => Console.WriteLine(n);
 act.BeginInvoke(10, null, null);
 Console.ReadKey();
 }
 }
 }

  9. using System;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.Remoting.Messaging;
 
 namespace

    ConsoleProject
 {
 class TestDelegateAsync
 {
 
 class MainClass
 {
 public static void Main(string[] args)
 {
 TestDelegateAsync test = new TestDelegateAsync();
 TestDelegate d = test.DoWork;
 d.BeginInvoke(test.CallbackMethod, null);
 Console.ReadKey();
 }
 
 }
 
 public delegate int TestDelegate();
 
 //࣮ߦ͍ͨ͠ॲཧ
 public int DoWork()
 {
 Console.WriteLine("DoWork");
 return 100;
 }
 
 //AsyncCallbackͷγάωνϟʹैͬͨίʔϧόοΫϝιου
 public void CallbackMethod(IAsyncResult ar)
 {
 //BeginInvokeͷ݁ՌΛ࢖ͬͯɺͦͷεϨου͔Β݁ՌΛநग़ͯ͠දࣔ
 TestDelegate @delegate = (TestDelegate)((AsyncResult)ar).AsyncDelegate;
 int result = @delegate.EndInvoke(ar);
 Console.WriteLine(result);
 }
 }
 }
 ࣮ߦ͍ͨ͠ॲཧ͕ೖΔσϦήʔτΛ༻ҙͯ͠ ࣮ߦ͍ͨ͠ॲཧΛॻ͘ γάωνϟʹैͬͨίʔϧόοΫϝιου ͜ͷΑ͏ʹͯ݁͠ՌΛಘΒΕΔ
  10. namespace ConsoleProject
 {
 class MainClass
 {
 public static void Main(string[]

    args)
 {
 Console.WriteLine("Hello World!");
 var a = new TestAsync();
 //10͔Β1·Ͱදࣔ͢Δ͕
 //ঢ়گʹԠͯ͡දࣔॱ͕มΘΔ
 for (int i = 10; i > 0; --i)
 a.Func(i);
 Console.ReadKey();
 }
 }
 
 class TestAsync
 {
 public void Func(int x)
 {
 Task.Run(() =>
 {
 Thread.Sleep(100 * x);
 Console.WriteLine(x++);
 });
 }
 }
 }
 جຊతͳ࢖͍ํ Ҿ਺Λදࣔͯ͠Ճࢉ͢Δ ॏ͍ͨॲཧ
  11. namespace ConsoleProject
 {
 class MainClass
 {
 public static void Main(string[]

    args)
 {
 Console.WriteLine("Hello World!");
 var a = new TestAsync();
 //10͔Β1·Ͱදࣔ͢Δ͕
 //ঢ়گʹԠͯ͡දࣔॱ͕มΘΔ
 Task[] tasks = new Task[10];
 for (int i = 10; i > 0; --i)
 tasks[i - 1] = a.Func(i);
 Task.WaitAll(tasks);
 Console.WriteLine("End All Tasks.");
 }
 }
 
 class TestAsync
 {
 public Task Func(int x)
 {
 return Task.Run(() =>
 {
 Thread.Sleep(100 * x);
 Console.WriteLine(x++);
 });
 }
 }
 } Runͷ໭Γ஋͸TaskܕͰ͋Δ (͖ͬ͞ͷϓϩάϥϜͰ͸ແࢹࣺͯͯͯͨ͠) શͯͷλεΫ(໭Γ஋Ͱಘͨ) ͕ऴྃ͢Δ·Ͱ଴ͭ
  12. namespace ConsoleProject
 {
 class MainClass
 {
 public static void Main(string[]

    args)
 {
 var a = new TestAsync();
 a.Func(100);
 }
 }
 
 class TestAsync
 {
 public void Func(int x)
 {
 var t = Task<int>.Run(() => x) .ContinueWith(a => Console.WriteLine(a.Result));
 t.Wait();
 }
 }
 } ໭Γ஋intͷॲཧΛͯ͠ɺͦͷ໭Γ஋Λ࢖༻ͨ͠ ίʔϧόοΫϝιουݺͼͩ͠ͷྫ ContinueWithϝιουͷҾ਺ʹೖ͖ͬͯͨ Runϝιουͷ໭Γ஋(Task<int>ܕ)ͷ ResultϓϩύςΟΛ࢖͑͹؆୯ʹ ίʔϧόοΫϝιουʹ஋ΛҾ͖౉ͤΔ
  13. using System;
 using System.Threading.Tasks;
 using System.Threading;
 
 class async_await
 {


    static void Main(string[] args)
 {
 var test = new AsyncTest();
 test.Test1();
 Console.ReadKey();
 }
 }
 
 class AsyncTest
 {
 //͕͔͔࣌ؒΔͨΊɺผεϨουͰ࣮ߦͯ͠΄͍͠ॲཧ
 //(ผεϨουͰߦͬͯ΋ଞʹѱӨڹΛ༩͑ͳ͍લఏ)
 public async void Test1()
 {
 await Task.Run(() =>
 {
 Thread.Sleep(2000);
 Console.WriteLine("Test1ॲཧA");
 });
 }
 } ͜ͷ··ͩͱॲཧऴྃલʹ Կ͔ΩʔΛԡ͢ͱڧ੍ऴྃ
  14. using System;
 using System.Threading.Tasks;
 using System.Threading;
 
 class async_await
 {


    static void Main(string[] args)
 {
 var test = new AsyncTest();
 test.Test1();
 Console.ReadKey();
 }
 }
 
 class AsyncTest
 {
 //εϨουΛੜ੒͠ɺܧଓλεΫΛߦΘͤΔ
 //ॲཧB΋ॲཧAͱಉ͡εϨουͰߦΘΕ͍ͯΔ͜ͱʹ஫ҙ
 public async void Test1()
 {
 await Task.Run(() =>
 {
 //࣌ؒͷ͔͔ΔॲཧΛͯ͠΋awaitʹΑͬͯॲཧB͸࣮ߦ͞Εͳ͍
 Thread.Sleep(100);
 Console.WriteLine("Test1ॲཧA");
 });
 Console.WriteLine("Test1ॲཧB");//ܧଓॲཧ
 }
 }
  15. using System;
 using System.Threading.Tasks;
 using System.Threading;
 
 
 class async_await


    {
 static void Main(string[] args)
 {
 var test = new AsyncTest();
 //√3Λදࣔ͢Δɻ
 //ResultϓϩύςΟʹΑΓॲཧऴྃ࣌·ͰϝΠϯεϨου΋ऴྃ͠ͳ͍
 Console.WriteLine(test.SumTwoAndSqrt(1.0, 2.0).Result);
 }
 }
 
 class AsyncTest
 {
 //2ͭͷҾ਺Λ଍ͯ͠ฏํࠜΛऔΔϝιουɻ
 //Sqrt͕return͢Δͷ͸doubleܕ͔ͩɺasyncम০ʹΑΓTask<double>ܕʹม׵͞ΕΔ
 public async Task<double> SumTwoAndSqrt(double num1, double num2)
 {
 //ຊདྷͳΒRun͸Task<double>Λฦ͕͢
 //awaitम০ʹΑΓ݁Ռͷdoubleܕม਺ͷΈ͕நग़͞Εͨ
 double result = await Task.Run(() => num1 + num2);
 return Math.Sqrt(result);//લͷॲཧ݁ՌresultΛ༰қʹ࢖͑Δ
 }
 }

  16. using System;
 using System.Threading.Tasks;
 using System.Threading;
 
 
 class MainClass


    {
 public static void Main(string[] args)
 {
 var t1 = Task.Run(() =>
 {
 Console.WriteLine(ReadTargetLocked());
 });
 var t2 = Task.Run(() =>
 {
 IncrementLocked();
 });
 Task.WaitAll(t1, t2);
 }
 
 static int target = 1110;
 static object lockObj = new object();
 
 static int ReadTargetLocked()
 {
 lock (lockObj)
 {
 Thread.Sleep(1000);
 return target;
 }
 }
 
 static void IncrementLocked()
 {
 lock (lockObj)
 {
 ++target;
 }
 }
 } ΦϒδΣΫτ͕ϩοΫ͞Ε͍ͯΔͷͰ ଞͷεϨου͕ͦͷΦϒδΣΫτΛ ࢀর͠Α͏ͱ͢Δͱ ΦϒδΣΫτ͕ղ์͞ΕΔ·Ͱ଴ػ (ϒϩοΫ) ͞ΕΔ ௨ৗ͸lock༻ʹΦϒδΣΫτ Λ1ͭ༻ҙ͓ͯ͘͠ ڞ༗͍ͨ͠ΦϒδΣΫτࣗ਎Ͱ΋͍͍͕ ϩοΫม਺Λpublicͱͯ͠ѻ͍͍ͨ৔߹͸ σουϩοΫͷݪҼʹͳΓ͔Ͷͳ͍ ϩοΫ༻ม਺Λ༻ҙ͢Ε͹publicͰ΋ແ໰୊
  17. TPL

  18. using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;


    using System.Threading;
 
 class TPL
 {
 static void Main(string[] args)
 {
 var act = new Action[10];
 for (int i = 0; i < 10; ++i)
 act[i] = new Action(Show);
 //Invoke͸શͯ׬ྃ͢Δ·ͰϝΠϯεϨου͕ऴྃ͠ͳ͍ 
 Parallel.Invoke(act);
 Console.WriteLine("exit...");
 }
 
 static void Show()
 {
 Console.WriteLine("Hello.");
 }
 }
  19. using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;


    using System.Threading;
 
 class TPL
 {
 static void Main(string[] args)
 {
 //For͸શͯ׬ྃ͢Δ·ͰϝΠϯεϨου͕ऴྃ͠ͳ͍
 Parallel.For(0, 10, n =>
 {
 Thread.Sleep(100);
 Console.WriteLine(n);
 });
 
 Console.WriteLine("exit...");
 }
 }
  20. using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;


    using System.Threading;
 
 class TPL
 {
 static void Main(string[] args)
 {
 //ForAll͸શ࣮ͯߦ͞ΕΔ·ͰϝΠϯεϨου͕ऴྃ͠ͳ͍
 Enumerable.Range(0, 10).AsParallel().ForAll(n =>
 {
 Thread.Sleep(100);
 Console.WriteLine(n);
 });
 
 Console.WriteLine("exit...");
 }
 }