static class · System.Threading

Parallel

public static class Parallel

Loops whose passes run on several threads at once.

Tipo
static class
Espacio de nombres
System.Threading
Ensamblado
System.Core
Acceso
public, static, abstract
Archivo fuente
Threading.ant

Herencia

Clases base
Any Parallel

Métodos

For(i32 fromInclusive, i32 toExclusive, func<i32> body)
#

static

body(i) for every i from fromInclusive to toExclusive, in parallel (in no set order); the calling thread takes part. An error a pass throws is thrown here, once every thread has stopped.

Invoke(func[] actions)
#

static

Runs each function, in parallel.

Miembros heredados (5)

Código fuente

Parallel en Antril, descompilado a partir de su Larva HIR.

System.Threading.Parallel.ant
// System.Threading.Parallel — System.Core (decompiled from Larva HIR)

import System;

into namespace System.Threading
{
	/// Loops whose passes run on several threads at once.
	public static class Parallel
	{
		public:
			/// body(i) for every i from `fromInclusive` to `toExclusive`, in parallel (in no set order); the calling thread
			/// takes part. An error a pass throws is thrown here, once every thread has stopped.
			For(i32 fromInclusive, i32 toExclusive, func<i32> body)
			{
				i32 count = toExclusive - fromInclusive;
				if (count <= 0)
					return;
				i32 threads = Environment.ProcessorCount;
				if (threads > count)
					threads = count;
				if (threads <= 1)
				{
					loop (i32 i = fromInclusive..toExclusive)
						body(i);
					return;
				}
				i32 chunk = count / (threads * 8);
				if (chunk < 1)
					chunk = 1;
				AtomicI32 next = new AtomicI32(fromInclusive);
				Shared<any?> failure = new Shared<any?>(null);
				AtomicI32 active = new AtomicI32();
				ManualResetEvent idle = new ManualResetEvent(false);
				AtomicI32 users = new AtomicI32(threads);
				func : bool run = () => { i32 start = next.Add(chunk) - chunk; if (start >= toExclusive) return false; try { i32 end = toExclusive - start < chunk ? toExclusive : start + chunk; loop (i32 i = start..end) body(i); } catch (any error) { failure.Value = error; next.Store(toExclusive); } return true; };
				func help = () => { loop (true) { active.Increment(); bool took = run(); if (active.Decrement() == 0 && next.Load() >= toExclusive) idle.Set(); if (!took) break; } if (users.Decrement() == 0) idle.Dispose(); };
				loop (i32 t = 1..threads)
					ThreadPool.QueueUserWorkItem(help);
				loop (run())
				{
				}
				loop (active.Load() != 0)
					idle.WaitOne();
				if (users.Decrement() == 0)
					idle.Dispose();
				if (failure.Value is any error)
					throw error;
			}

			/// Runs each function, in parallel.
			Invoke(func[] actions)
			{
				For(0, actions.Length, i => { actions[i](); });
			}
	}
}
Esc