private void ReproduceByParallelThreads() { #region Parallel Reproduct Code Thread[] th = new Thread[countCPUCore]; // Create a semaphore that can satisfy up to three // concurrent requests. Use an initial count of zero, // so that the entire semaphore count is initially // owned by the main program thread. // Semaphore sem = new Semaphore(countCPUCore, countCPUCore); bool[] isAlive = new bool[countCPUCore]; bool[] isCompleted = new bool[countCPUCore]; int length = (Npop - N_keep) / countCPUCore; int divideReminder = (Npop - N_keep) % countCPUCore; for (int proc = 0; proc < th.Length; proc++) { ThreadToken tt = new ThreadToken(proc, length + ((proc == countCPUCore - 1) ? divideReminder : 0), N_keep + (proc * length)); th[proc] = new Thread(new ParameterizedThreadStart((x) => { // Entered sem.WaitOne(); isAlive[((ThreadToken)x).No] = true; // work ... PReproduction(((ThreadToken)x).startIndex, ((ThreadToken)x).length, ((ThreadToken)x).rand); // We have finished our job, so release the semaphore isCompleted[((ThreadToken)x).No] = true; sem.Release(); })); setThreadPriority(th[proc]); th[proc].Start(tt); } startloop: foreach (bool alive in isAlive) // wait parent starter for start all children. if (!alive) goto startloop; endLoop: sem.WaitOne(); foreach (bool complete in isCompleted) // wait parent to interrupt for finishes all of children jobs. if (!complete) goto endLoop; // Continue Parent Work sem.Close(); #endregion }
private void ReproduceByParallelTask() { #region Parallel Reproduct Code Task[] tasks = new Task[countCPUCore]; int length = (Npop - N_keep) / countCPUCore; int divideReminder = (Npop - N_keep) % countCPUCore; for (int proc = 0; proc < tasks.Length; proc++) { ThreadToken tt = new ThreadToken(proc, length + ((proc == countCPUCore - 1) ? divideReminder : 0), N_keep + (proc * length)); tasks[proc] = Task.Factory.StartNew(x => { // work ... PReproduction(((ThreadToken)x).startIndex, ((ThreadToken)x).length, ((ThreadToken)x).rand); }, tt, tokenSource.Token);// TaskCreationOptions.AttachedToParent); } // When user code that is running in a task creates a task with the AttachedToParent option, // the new task is known as a child task of the originating task, // which is known as the parent task. // You can use the AttachedToParent option to express structured task parallelism, // because the parent task implicitly waits for all child tasks to complete. // The following example shows a task that creates one child task: Task.WaitAll(tasks); // or //Block until all tasks complete. //Parent.Wait(); // when all task are into a parent task #endregion }