I wonder if the same thing is possible with rclone. rclone on iSH sometimes works well, but randomly crashes after certain time of operation, and I would like to try single-threaded mode to test out if it works better. When I run certain commands with -i flag, it does not seem to crash.
I have seen that flags like --multi-thread-streams=N exists, but it only governs usage of threads for downloading large files. I am wondering to know if
Run the command 'rclone version' and share the full output of the command.
rclone v1.57.0
os/version: alpine 3.14.3
os/kernel: 4.20.69-ish (i686)
os/type: linux
os/arch: 386
go/version: go1.17.2
go/linking: static
go/tags: none
Which cloud storage system are you using? (eg Google Drive)
Google Drive
The command you were trying to run (eg rclone copy /tmp remote:tmp)
What you want is to tell the Go runtime to only use one thread... Go threads (as set with --transfers/--checkers are not OS threads and the go runtime multiplexes them onto OS threads)
I think if you set the environment variable export GOMAXPROCS=1 that should make it so Go runs with only one OS thread active at once. As I understand the docs there may be other inactive OS threads though so this may not work depending on exactly what the bug in iSH is!
It would probably be worth setting the environment variable export GODEBUG=asyncpreemptoff=1 to turn off preemptive scheduling of the go threads as that is a likely source of bugs in iSH (there have been quite a few bugs in the Linux kernel with this!)
Setting GODEBUG=asyncpreemptoff=1 have fixed the issue. Thanks a lot! I mainly use rclone for Obsidian vault synchronization on iOS. It is great that I can use existing great CLI tools on closed garden like iOS.
It isn't a very well named variable, but yes it controls the number of threads the go runtime starts. (In the Linux world a thread is pretty much a new process but with more memory sharing going on so I expect that is where the confusion came from!).
I think what is happening here is when the go runtime is blocked on a syscall it starts a new thread regardless of GOMAXPROCS - a thread which will die once the syscall has returned.
So GOMAXPROCS regulates the number of active threads - there may be other threads waiting on syscalls.
I think that is right - the Go runtime is complicated!
Interesting analysis. I seem to remember reading that goroutines can swap between OS threads which might mean threads that were used for blocked syscalls become active threads later. If that is the case then that means Go is keeping those threads in a threadpool which makes sense too.
That other thread could also be some kind of master thread. I don't know enough about the go runtime internals to be sure!