# Async limit

**URL:** https://discourse.julialang.org/t/async-limit/62732
**Category:** New to Julia
**Tags:** question
**Created:** [June 11, 2021, 12:30pm UTC](https://discourse.julialang.org/t/async-limit/62732 "2021-06-11T12:30:58Z")
**Posts on this page:** 1
**Showing post:** 3

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [August 1, 2021, 9:23pm UTC](https://discourse.julialang.org/t/async-limit/62732/3 "2021-08-01T21:23:04Z")

</div>

I recommend using “worker pool” pattern I described in a quick tutorial [Concurrency patterns for controlled parallelisms](https://juliafolds.github.io/data-parallelism/tutorials/concurrency-patterns/) ([discussion](https://discourse.julialang.org/t/tutorial-concurrency-patterns-for-controlled-parallelisms/62651)) which is just a simple wrapper around a channel and tasks.

Semaphore may be useful for simple things sometimes but lock and lock-like constructs often yield non-composable and hard-to-read code. “Don’t communicate by sharing memory, share memory by communicating.” is one of very practical [Go Proverbs](https://go-proverbs.github.io/). Since a lot of good practical ideas in concurrency are developed in Go, I think it’d be useful to steal some patterns from Go. Some of them are discussed in my tutorial I linked above.

It is also a waste of resource to allocate tasks and _then_ limit how many of them can run. It is usually much cleaner to match the bound and the number of tasks in the first place, in terms of performance and code structure.

> [@oxinabox](#):
>
> I have also seen a `Channel` used as a adhoc semaphore.  
> Which is marginally faster since it is not having to take out locks etc.

`Channel` uses lock internally.

> [@oxinabox](#):
>
> change from tasks to threads later

A nitpick: There’s no way in Julia to “change tasks to threads.” There is no language-level API to create an OS thread. The only thing you can do is to create a _task_ which comes with two flavors:

- A _task_ scheduled with `Threads.@spawn` can be executed by arbitrary worker threads.
- A task scheduled with `@async` uses the same worker thread as the parent task.

(I’m sure you already know this since you are mentioning the “sticky bit.” This is rather for avoiding confusion of other readers.)

---

_[View the full topic](https://discourse.julialang.org/t/async-limit/62732)._
