diff --git a/HISTORY.md b/HISTORY.md index 6c2ca03662233..ce4e9982a2c6b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -36,9 +36,10 @@ Language changes * Julia now defaults to 1 "interactive" thread, in addition to the 1 default "worker" thread. i.e. `-t1,1`. This means in default configuration the main task and repl (when in interactive mode), which both run on thread 1, now run within the `interactive` threadpool. The libuv IO loop also runs on thread 1, - helping efficient utilization of the worker threadpool used by `Threads.@spawn`. Pass `0` to disable the - interactive thread i.e. `-t1,0` or `JULIA_NUM_THREADS=1,0`, or `-tauto,0` etc. The zero is explicitly - required to disable it, `-t2` will set the equivalent of `-t2,1` ([#57087]). + helping efficient utilization of the worker threadpool used by `Threads.@spawn`. Asking for specifically 1 thread + (`-t1`/`JULIA_NUM_THREADS=1`) or passing `0` will disable the interactive thread i.e. `-t1,0` or `JULIA_NUM_THREADS=1,0` + , or `-tauto,0` etc. Asking for more than 1 thread will enable the interactive thread so + `-t2` will set the equivalent of `-t2,1` ([#57087]). * When a method is replaced with an exactly equivalent one, the old method is not deleted. Instead, the new method takes priority and becomes more specific than the old method. Thus if the new method is deleted later, the old method will resume operating. This can be useful in mocking frameworks (as in SparseArrays, diff --git a/doc/src/manual/multi-threading.md b/doc/src/manual/multi-threading.md index ec470f867cc47..401169e9c2132 100644 --- a/doc/src/manual/multi-threading.md +++ b/doc/src/manual/multi-threading.md @@ -8,7 +8,7 @@ of Julia multi-threading features. By default, Julia starts up with 2 threads of execution; 1 worker thread and 1 interactive thread. This can be verified by using the command [`Threads.nthreads()`](@ref): -```jldoctest +```julia julia> Threads.nthreads(:default) 1 julia> Threads.nthreads(:interactive) @@ -37,6 +37,7 @@ each threadpool. !!! compat "Julia 1.12" Starting by default with 1 interactive thread, as well as the 1 worker thread, was made as such in Julia 1.12 + If the number of threads is set to 1 by either doing `-t1` or `JULIA_NUM_THREADS=1` an interactive thread will not be spawned. Lets start Julia with 4 threads: @@ -144,6 +145,8 @@ julia> nthreads(:interactive) julia> nthreads() 3 ``` +!!! note + Explicitly asking for 1 thread by doing `-t1` or `JULIA_NUM_THREADS=1` does not add an interactive thread. !!! note The zero-argument version of `nthreads` returns the number of threads diff --git a/src/jloptions.c b/src/jloptions.c index 21d034a666b1d..7ebbec2181e99 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -669,6 +669,9 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) if (nthreadsi == 0) jl_options.nthreadpools = 1; } + } else if (nthreads == 1) { // User asked for 1 thread so don't add an interactive one + jl_options.nthreadpools = 1; + nthreadsi = 0; } jl_options.nthreads = nthreads + nthreadsi; } diff --git a/src/threading.c b/src/threading.c index 11726f5452cf0..6cd8eef558eb6 100644 --- a/src/threading.c +++ b/src/threading.c @@ -740,6 +740,8 @@ void jl_init_threading(void) if (errno != 0 || endptr == cp || nthreads <= 0) nthreads = 1; cp = endptr; + if (nthreads == 1) // User asked for 1 thread so lets assume they dont want an interactive thread + nthreadsi = 0; } if (*cp == ',') { cp++; diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 12b13c1984a5e..716660da2b53d 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -348,6 +348,7 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` # -t, --threads code = "print(Threads.threadpoolsize())" + code2 = "print(Threads.maxthreadid())" cpu_threads = ccall(:jl_effective_threads, Int32, ()) @test string(cpu_threads) == read(`$exename --threads auto -e $code`, String) == @@ -358,6 +359,11 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` withenv("JULIA_NUM_THREADS" => nt) do @test read(`$exename --threads=2 -e $code`, String) == read(`$exename -t 2 -e $code`, String) == "2" + if nt === nothing + @test read(`$exename -e $code2`, String) == "2" #default + interactive + elseif nt == "1" + @test read(`$exename -e $code2`, String) == "1" #if user asks for 1 give 1 + end end end # We want to test oversubscription, but on manycore machines, this can