This language bar is your friend. Select your favorite languages!
Select your favorite languages :
- Or search :
Idiom #56 Launch 1000 parallel tasks and wait for completion
Fork-join : launch the concurrent execution of procedure f with parameter i from 1 to 1000.
Tasks are independent and f(i) doesn't return any value.
Tasks need not run all at the same time, so you may use a pool.
Wait for the completion of the 1000 tasks and then print "Finished".
size_t taskCount = 1000;
auto remainingTasks = std::latch(static_cast<std::ptrdiff_t>(taskCount));
auto f = [&remainingTasks](int i) {
// do work
remainingTasks.count_down();
};
std::vector<std::jthread> threads{ 10 };
for (auto i = 0; i < taskCount; i++) {
auto& workerThread = threads[i % 10];
if (workerThread.joinable()) {
workerThread.join();
}
workerThread = std::jthread(f, i);
}
remainingTasks.wait();
std::cout << "Finished";
Latch is used to wait until all tasks are completed. Simulated thread pool with vector of jthreads.
int numTasks = 1000;
Task<int>[] output = new System.Threading.Tasks.Task<int>[numTasks];
for (int i = 0; i < numTasks; i++)
{
output[i] = Task.Factory.StartNew(
new Func <object, int>(LongRunningOperation), 2000);
}
Task.WaitAll(output);
int LongRunningOperation(object objMs)
{
int ms = (int)objMs;
Thread.Sleep(ms);
return ms;
}
foreach(i; parallel(iota(1,1001))){
f(i);
}
writeln("Finished");
The wait is built into the parallel foreach. The iota creates a range of 1..1000. This is using the default threadpool.
List<Future> tasks = [];
for (int i = 1; i <= 1000; i++) {
tasks.add(Isolate.spawn(f, i));
}
await Future.wait(tasks);
print("finished");
# 1
f = &(IO.puts(&1))
# 2
printTimes = &(for n <- 1..&1, do: spawn(fn -> f.(n) end))
# 3
fn -> printTimes.(1000) end |> Task.async |> Task.await
IO.puts("Finished")
1: f prints argument to the console.
2: printTimes calls f concurrently n times
3: Task.async/await waits for printTimes.(1000) to finish
2: printTimes calls f concurrently n times
3: Task.async/await waits for printTimes.(1000) to finish
run_n_times(Fun, N) ->
Self = self(),
Task = fun (I) -> spawn(?MODULE, run_task_and_notify_completion, [Self, Fun, I]) end,
lists:foreach(Task, lists:seq(1, N)),
wait_for_n_tasks(N).
run_task_and_notify_completion(ParentPid, Fun, Arg) ->
Fun(Arg),
ParentPid ! done.
wait_for_n_tasks(0) ->
io:format("Finished~n");
wait_for_n_tasks(N) when N > 0 ->
receive
done ->
ok
end,
wait_for_n_tasks(N-1).
run_n_times(F, 1000).
F is a fun, for example:
F = fun (I) -> io:format("~p~n", [I]) end,
F = fun (I) -> io:format("~p~n", [I]) end,
var wg sync.WaitGroup
wg.Add(1_000)
for i := range 1_000 {
go func() {
f(i)
wg.Done()
}()
}
wg.Wait()
1,000 goroutines
const tasks = [];
for (let i = 0; i < 1000; i++) {
tasks.push(f(i));
}
await Promise.all(tasks);
console.log("Finished");
Uses the async function f to create 1000 Promises which are await-ed. All tasks are run in a single thread.
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 1; i <= 1000; i++) {
Task task = new Task(i);
executor.submit(() -> f(i));
}
executor.shutdown();
executor.awaitTermination(10L, TimeUnit.MINUTES);
System.out.println("Finished");
4 is the size of the thread pool.
It will wait max 10mn.
With lambdas, no wrapper is necessary.
It will wait max 10mn.
With lambdas, no wrapper is necessary.
class Task implements Runnable {
int i;
Task(int i) {
this.i = i;
}
@Override
public void run() {
f(i);
}
}
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 1; i <= 1000; i++) {
Task task = new Task(i);
executor.submit(task);
}
executor.shutdown();
executor.awaitTermination(10L, TimeUnit.MINUTES);
System.out.println("Finished");
4 (in this example) is the size of the thread pool.
It will wait max 10mn.
It will wait max 10mn.
(1..1000)
.map { i ->
CoroutineScope(Dispatchers.Default).async {
f(i)
}
}
.awaitAll()
print("Finished")
Leverages kotlin's coroutines to run 1000 tasks in parallel using a job pool about the size of the computer's cpu core count.
Must be run from inside a coroutine context, eg. runBlocking { /* here */ }
Must be run from inside a coroutine context, eg. runBlocking { /* here */ }
for my $i (1 .. 1000) {
threads->create('f', $i);
}
sleep 3 while threads->list(threads::running);
print "Finished\n";
# optional: threads library wants you to explicitly join or detach
# your threads before exiting program.
$_->join() for threads->list(threads::joinable);
If you don't use the optional line, you'll get a warning about threads not joined/detached when your program stops.
def f(i):
i * i
with Pool(1000) as p:
p.map(func=f, iterable=range(1, 1001))
print('Finished')
let threads: Vec<_> = (0..1000).map(|i| thread::spawn(move || f(i))).collect();
for t in threads {
t.join();
}