SHARE
TWEET

Untitled

a guest May 19th, 2019 60 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Async and Parallel Prgramming
  2.  
  3. ## 1- Understanding the Dangers of Concurrency
  4.  
  5. ### Race condition
  6.  
  7. A race condition exists when the outcome depends on the timing of events
  8.  
  9. ### Shared resources (Most common pitfall)
  10.  
  11. ```csharp
  12. int sum = 0;
  13. Task.Factory.StartNew(() => {
  14.     sum = sum + obj1.Computation();
  15. })
  16. Task.Factory.StartNew(() => {
  17.     sum = sum + obj2.Computation();
  18. })
  19. ```
  20.  
  21. ### Sequential to Parallel
  22.  
  23. ```csharp
  24. // Sequential
  25. private int SearchFiles(List<string> filenames, string pattern)
  26. {
  27.     int hits = 0;
  28.  
  29.     Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  30.  
  31.     foreach (string f in filenames)
  32.     {
  33.         byte[] bytes = File.ReadAllBytes(f);
  34.  
  35.         string contents = System.Text.Encoding.UTF8.GetString(bytes);
  36.  
  37.         Match m = re.Match(contents);
  38.  
  39.         while(m.Success)
  40.         {
  41.             hits++;
  42.             m = m.NextMatch();
  43.         }
  44.     }
  45.  
  46.     return hits;
  47. }
  48.  
  49. // Parallel
  50. private int SearchFiles(List<string> filenames, string pattern)
  51. {
  52.     int hits = 0;
  53.  
  54.     Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  55.  
  56.     var tasks = new List<Task>();
  57.  
  58.     foreach (string f in filenames)
  59.     {
  60.         var t = new Task.Factory.StartNew((arg) => {
  61.             var fn = (string)arg;
  62.  
  63.             byte[] bytes = File.ReadAllBytes(fn);
  64.  
  65.             string contents = System.Text.Encoding.UTF8.GetString(bytes);
  66.  
  67.             Match m = re.Match(contents);
  68.  
  69.             while(m.Success)
  70.             {
  71.                 hits++; // Shared Resource
  72.                 m = m.NextMatch();
  73.             }
  74.         });
  75.  
  76.         tasks.Add(t);
  77.     }
  78.  
  79.     tasks.WaitAll(tasks.ToArray());
  80.  
  81.     return hits;
  82. }
  83. ```
  84.  
  85. ### Solutions
  86.  
  87. - Redesign - To eliminate shared resources (eg. Each task uses only local storage)
  88. - Thread-safe - TPL offers thread-safe data structures (eg. ConcurrentDictionary)
  89. - Synchronization - To control access critical section (eg. Lock, Interlocked )
  90.  
  91. ### Solution 1 - Locking
  92.  
  93. ```csharp
  94. private int SearchFiles(List<string> filenames, string pattern)
  95. {
  96.     int hits = 0;
  97.  
  98.     Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  99.  
  100.     var tasks = new List<Task>();
  101.     var l = new object();
  102.  
  103.     foreach (string f in filenames)
  104.     {
  105.         var t = new Task.Factory.StartNew((arg) => {
  106.             var fn = (string)arg;
  107.  
  108.             byte[] bytes = File.ReadAllBytes(fn);
  109.  
  110.             string contents = System.Text.Encoding.UTF8.GetString(bytes);
  111.  
  112.             Match m = re.Match(contents);
  113.  
  114.             while(m.Success)
  115.             {
  116.                 lock (l)
  117.                 {
  118.                     hits++;
  119.                 }
  120.                 m = m.NextMatch();
  121.             }
  122.         });
  123.  
  124.         tasks.Add(t);
  125.     }
  126.  
  127.     tasks.WaitAll(tasks.ToArray());
  128.  
  129.     return hits;
  130. }
  131. ```
  132.  
  133. ### Solution 2 - InterLocking
  134.  
  135. ```csharp
  136. private int SearchFiles(List<string> filenames, string pattern)
  137. {
  138.     int hits = 0;
  139.  
  140.     Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  141.  
  142.     var tasks = new List<Task>();
  143.  
  144.     foreach (string f in filenames)
  145.     {
  146.         var t = new Task.Factory.StartNew((arg) => {
  147.             var fn = (string)arg;
  148.  
  149.             byte[] bytes = File.ReadAllBytes(fn);
  150.  
  151.             string contents = System.Text.Encoding.UTF8.GetString(bytes);
  152.  
  153.             Match m = re.Match(contents);
  154.  
  155.             while(m.Success)
  156.             {
  157.                 System.Threading.Interlocked.Increment(ref hits);
  158.                 m = m.NextMatch();
  159.             }
  160.         });
  161.  
  162.         tasks.Add(t);
  163.     }
  164.  
  165.     tasks.WaitAll(tasks.ToArray());
  166.  
  167.     return hits;
  168. }
  169. ```
  170.  
  171. ### Solution 3 - Lock-free
  172.  
  173. ```csharp
  174. private int SearchFiles(List<string> filenames, string pattern)
  175. {
  176.     int hits = 0;
  177.  
  178.     Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  179.  
  180.     var tasks = new List<Task<int>>();
  181.  
  182.     foreach (string f in filenames)
  183.     {
  184.         var t = new Task.Factory.StartNew<int>((arg) => {
  185.             var lhits = 0;
  186.             var fn = (string)arg;
  187.  
  188.             byte[] bytes = File.ReadAllBytes(fn);
  189.  
  190.             string contents = System.Text.Encoding.UTF8.GetString(bytes);
  191.  
  192.             Match m = re.Match(contents);
  193.  
  194.             while(m.Success)
  195.             {
  196.                 lhits++;
  197.                 m = m.NextMatch();
  198.             }
  199.  
  200.             return lhits++;
  201.         });
  202.  
  203.         tasks.Add(t);
  204.     }
  205.  
  206.     tasks.WaitAll(tasks.ToArray());
  207.  
  208.     var hits = 0;
  209.     foreach (var t in tasks)
  210.         hits += t.Result;
  211.  
  212.     return hits;
  213. }
  214. ```
  215.  
  216. ### Wait All One by One Pattern
  217.  
  218. ```csharp
  219. private int SearchFiles(List<string> filenames, string pattern)
  220. {
  221.     int hits = 0;
  222.  
  223.     Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  224.  
  225.     var tasks = new List<Task<int>>();
  226.  
  227.     foreach (string f in filenames)
  228.     {
  229.         var t = new Task.Factory.StartNew<int>((arg) => {
  230.             var lhits = 0;
  231.             var fn = (string)arg;
  232.  
  233.             byte[] bytes = File.ReadAllBytes(fn);
  234.  
  235.             string contents = System.Text.Encoding.UTF8.GetString(bytes);
  236.  
  237.             Match m = re.Match(contents);
  238.  
  239.             while(m.Success)
  240.             {
  241.                 lhits++;
  242.                 m = m.NextMatch();
  243.             }
  244.  
  245.             return lhits++;
  246.         });
  247.  
  248.         tasks.Add(t);
  249.     }
  250.  
  251.     // tasks.WaitAll(tasks.ToArray());
  252.     var results = WaitAllOneByOne(tasks);
  253.  
  254.     // var hits = 0;
  255.     // foreach (var t in tasks)
  256.     //     hits += t.Result;
  257.     int hits = results.AsParallel().Sum();
  258.  
  259.     return hits;
  260. }
  261.  
  262. private List<int> WaitAllOneByOne(List<Task<int> tasks)
  263. {
  264.     var results = new List<int>();
  265.  
  266.     while(tasks.Count > 0)
  267.     {
  268.         int i = Task.WaitAny(tasks.ToArray());
  269.         results.Add(tasks[i].Result);
  270.         tasks.RemoveAt(i);
  271.     }
  272.  
  273.     return results;
  274. }
  275. ```
  276.  
  277. ### Shared objects and non thread safe classes
  278.  
  279. ```csharp
  280. var results = new List<int>(); // non thread safe
  281. var rand = new Random(); // non thread safe
  282.  
  283. for (int i = 0; i < n; i++)
  284. {
  285.     Task.Factory.StartNew(() => {
  286.         int r = SimulationMethod(rand);
  287.         results.Add(r);
  288.     });
  289. }
  290. ```
  291.  
  292. ### Solution - Use thread safe classes
  293.  
  294. ```csharp
  295. var results = new ConcurrentQueue<int>();
  296.  
  297. for (int i = 0; i < n; i++)
  298. {
  299.     Task.Factory.StartNew(() => {
  300.         var rng = new RNGCryptoServiceProvider();
  301.         var data = byte[4];
  302.         rng.GetBytes(data);
  303.         int seed = BitConverter.ToInt32(data, 0);
  304.         var rand = new Random(seed);
  305.  
  306.         int r = SimulationMethod(rand);
  307.         results.Enqueue(r);
  308.     });
  309. }
  310. ```
  311.  
  312. ### Solution 5 - Thread safe object
  313.  
  314. ```csharp
  315. var tasks = new List<Task<int>>();
  316.  
  317. private int SearchFiles(List<string> filenames, string pattern)
  318. {
  319.     int hits = 0;
  320.  
  321.     Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  322.  
  323.     var tasks = new List<Task<int>>();
  324.  
  325.     foreach (string f in filenames)
  326.     {
  327.         var t = new Task.Factory.StartNew<int>((arg) => {
  328.             var lhits = 0;
  329.             var fn = (string)arg;
  330.  
  331.             byte[] bytes = File.ReadAllBytes(fn);
  332.  
  333.             // Non thread safe
  334.             // string contents = System.Text.Encoding.UTF8.GetString(bytes);
  335.             // Thread safe
  336.             var encoding = new System.Text.UTF8Encoding();
  337.             string contents = encoding.GetString(bytes)
  338.  
  339.             Match m = re.Match(contents);
  340.  
  341.             while(m.Success)
  342.             {
  343.                 lhits++;
  344.                 m = m.NextMatch();
  345.             }
  346.  
  347.             return lhits++;
  348.         });
  349.  
  350.         tasks.Add(t);
  351.     }
  352.  
  353.     tasks.WaitAll(tasks.ToArray());
  354.  
  355.     var hits = 0;
  356.     foreach (var t in tasks)
  357.         hits += t.Result;
  358.  
  359.     return hits;
  360. }
  361. ```
  362. ### Solution 6 - Local object
  363.  
  364. ```csharp
  365. var tasks = new List<Task<int>>();
  366.  
  367. private int SearchFiles(List<string> filenames, string pattern)
  368. {
  369.     int hits = 0;
  370.  
  371.     // Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  372.  
  373.     var tasks = new List<Task<int>>();
  374.  
  375.     foreach (string f in filenames)
  376.     {
  377.         var t = new Task.Factory.StartNew<int>((arg) => {
  378.             var lhits = 0;
  379.             var fn = (string)arg;
  380.  
  381.             byte[] bytes = File.ReadAllBytes(fn);
  382.  
  383.             var encoding = new System.Text.UTF8Encoding();
  384.             string contents = encoding.GetString(bytes)
  385.  
  386.             // Local object
  387.             Regex re = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multipline);
  388.             Match m = re.Match(contents);
  389.  
  390.             while(m.Success)
  391.             {
  392.                 lhits++;
  393.                 m = m.NextMatch();
  394.             }
  395.  
  396.             return lhits++;
  397.         });
  398.  
  399.         tasks.Add(t);
  400.     }
  401.  
  402.     tasks.WaitAll(tasks.ToArray());
  403.  
  404.     var hits = 0;
  405.     foreach (var t in tasks)
  406.         hits += t.Result;
  407.  
  408.     return hits;
  409. }
  410. ```
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top