Golang daemon with goroutines won't stop executing - multithreading

I've created a daemon that has the goal to consume queues in parallel. To test if it keeps executing in the background I've implemented a function that creates a file every 10 seconds until it reaches X, where X is the highest number of processes that I configured for the queues. The parameters for the queues are defined on the config.yaml file.
The problem now is that even though I stop and remove the daemon, it seems that the program keeps running and creating files... I've tried building and running the program again, exiting it, ending the processes, deleting the files, but nothing seems to work, files keep being created on the program directory.
You can check the program code here, and the config file here.
Do you have any idea how I can solve this problem?
Thanks in advance!

This code will never exit until it does processing for len(queues) times. It is not a concurrent code - all in main body - and there is no signal to tell the code to stop. The problem is here:
case "run":
// Installing the service
installed, err := service.Install()
logError(err, installed)
// Starting the service
started, err := service.Start()
logError(err, started)
if err == nil {
// Creating a goroutine and executing the queue's processes in parallel
for i := 0; i < len(queues); i++ {
go startProcessing(queues[i])
time.Sleep(time.Second) // Waiting for other functions to execute
}
select {} // To prevent the goroutine from exiting the main func
}
fmt.Println(started)
As it can be seen the select{} line will sit there and run for ever! :) It is better to move this case clauses, into their's own goroutines and have a quit signal there like this:
select {
case <-quit:
return
}
Though this is not the cleanest way to handle start/stop in Go apps; it just shows the problem.

When asking questions like this you should consider putting together a MCVE.
That way, since the problem size is a lot smaller, you might figure out the problem on your own.
If not, at least the people here will have an easier time helping you.

Related

Do goroutines keep running even if main function is terminated?

I am running a server where main fires off several go routines. like this:
main() {
go someFn(){
// will run for infinite time()
}
go otherFn()
}
I have two doubts:
what if the main function is exited? will these threads will still run or will terminate with the main function?
if no, then what is the best method to make the main function run forever/ or run till I need it? currently, I am using select{} command for making it run forever! is there any better and more efficient method available than select{}
I would recommend to read the language specification in its entirety — Go is one of a very small number of laguages whose language spec can really be read over two lunches (or a single one — if this is your, I dunno, third of fourth programming language).
To cite it:
Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.
I would add that logically making main wait all non-main goroutines would be a bad thing for two reasons:
That would easily create situations where you could wait for a program to shut down for some indeterminate amount of time even if you do not want that (and you not always want that).
Logically, that would require inventing a "special" way to end main — something like abort(3) from C, and having such a way is a sure path for it to be abused.
Any sensible usage of goroutines where you actually need to wait on them anyway requires explicit synchronisation — just per the language specification and its memory model.
That is, when you want to wait on outstanding goroutines, you must do that explicitly.
The program exits when the function main() returns.
If one of someFn or otherFn runs forever, then call that function directly at the end of main. The main function never exits with this change.
If neither function runs forever, the use a sync.WaitGroup to wait on the goroutines and then exit.
The empty select statement select {} efficiently blocks a goroutine forever.
[Do] go routines keeps on running even if main function is terminated?
No.
This is asked once a week.
In my opinion, when it is difficult to remember a concept the best thing is to code such concept yourself.
Here is a simple program which demonstrates that go routines are terminated when main function exits:
package main
import (
"log"
"os"
"time"
)
func main() {
f, err := os.Create("./test.txt")
if err != nil {
log.Fatal("can not write to a file", err)
}
go func() {
for {
f.WriteString("new line created at: " + time.Now().String() + "\n")
time.Sleep(1 * time.Second)
}
}()
time.Sleep(5 * time.Second)
// writing to the file by goroutine will be finished in 5 seconds
// when main exits
}

Golang: can WaitGroup leak with go-routines

I am planning to implement a go-routine and have a sync.WaitGroup to synchronize end of a created go-routine. I create a thread essentially using go <function>. So it is something like:
main() {
var wg sync.WaitGroup
for <some condition> {
go myThread(wg)
wg.Add(1)
}
wg.wait()
}
myThread(wg sync.WaitGroup) {
defer wg.Done()
}
I have earlier worked with pthread_create which does fail to create a thread under some circumstances. With that context, is it possibly for the above go myThread(wg) to fail to start, and/or run wg.Done() if the rest of the routine behaves correctly? If so, what would be reported and how would the error be caught? My concern is a possible leak in wg due to wg.Add(1) following the thread creation. (Of course it may be possible to use wg.Add(1) within the function, but that leads to other races between the increment and the main program waiting).
I have read through numerous documentation of go-routines and there is no mention of a failure in scheduling or thread creation anywhere. What would be the case if I create billions of threads and exhaust bookkeeping space? Would the go-routine still work and threads still be created?
I don't know of any possible way for this to fail, and if it is possible, it would result in a panic (and therefor application crash). I have never seen it happen, and I'm aware of examples of applications running millions of goroutines. The only limiting factor is available memory to allocate the goroutine stack.
go foo() is not like pthread_create. Goroutines are lightweight green threads handled by the Go runtime, and scheduled to run on OS threads. Starting a goroutine does not start a new OS thread.
The problem with your code is not in starting a goroutine (which cannot "fail" per se) or that like but in the use of sync.WaitGroup. Your code has two major bugs:
You must do wg.Add(1) before launching the goroutine as otherwise the Done() could be executed before the Add(1).
You must not copy a sync.WaitGroup. Your code makes a copy while calling myThread().
Both issues are explained in the official documentation to sync.WaitGroup and the given example in https://golang.org/pkg/sync/#WaitGroup

Goroutines are cooperatively scheduled. Does that mean that goroutines that don't yield execution will cause goroutines to run one by one?

From: http://blog.nindalf.com/how-goroutines-work/
As the goroutines are scheduled cooperatively, a goroutine that loops continuously can starve other goroutines on the same thread.
Goroutines are cheap and do not cause the thread on which they are multiplexed to block if they are blocked on
network input
sleeping
channel operations or
blocking on primitives in the sync package.
So given the above, say that you have some code like this that does nothing but loop a random number of times and print the sum:
func sum(x int) {
sum := 0
for i := 0; i < x; i++ {
sum += i
}
fmt.Println(sum)
}
if you use goroutines like
go sum(100)
go sum(200)
go sum(300)
go sum(400)
will the goroutines run one by one if you only have one thread?
A compilation and tidying of all of creker's comments.
Preemptive means that kernel (runtime) allows threads to run for a specific amount of time and then yields execution to other threads without them doing or knowing anything. In OS kernels that's usually implemented using hardware interrupts. Process can't block entire OS. In cooperative multitasking thread have to explicitly yield execution to others. If it doesn't it could block whole process or even whole machine. That's how Go does it. It has some very specific points where goroutine can yield execution. But if goroutine just executes for {} then it will lock entire process.
However, the quote doesn't mention recent changes in the runtime. fmt.Println(sum) could cause other goroutines to be scheduled as newer runtimes will call scheduler on function calls.
If you don't have any function calls, just some math, then yes, goroutine will lock the thread until it exits or hits something that could yield execution to others. That's why for {} doesn't work in Go. Even worse, it will still lead to process hanging even if GOMAXPROCS > 1 because of how GC works, but in any case you shouldn't depend on that. It's good to understand that stuff but don't count on it. There is even a proposal to insert scheduler calls in loops like yours
The main thing that Go's runtime does is it gives its best to allow everyone to execute and don't starve anyone. How it does that is not specified in the language specification and might change in the future. If the proposal about loops will be implemented then even without function calls switching could occur. At the moment the only thing you should remember is that in some circumstances function calls could cause goroutine to yield execution.
To explain the switching in Akavall's answer, when fmt.Printf is called, the first thing it does is checks whether it needs to grow the stack and calls the scheduler. It MIGHT switch to another goroutine. Whether it will switch depends on the state of other goroutines and exact implementation of the scheduler. Like any scheduler, it probably checks whether there're starving goroutines that should be executed instead. With many iterations function call has greater chance to make a switch because others are starving longer. With few iterations goroutine finishes before starvation happens.
For what its worth it. I can produce a simple example where it is clear that the goroutines are not ran one by one:
package main
import (
"fmt"
"runtime"
)
func sum_up(name string, count_to int, print_every int, done chan bool) {
my_sum := 0
for i := 0; i < count_to; i++ {
if i % print_every == 0 {
fmt.Printf("%s working on: %d\n", name, i)
}
my_sum += 1
}
fmt.Printf("%s: %d\n", name, my_sum)
done <- true
}
func main() {
runtime.GOMAXPROCS(1)
done := make(chan bool)
const COUNT_TO = 10000000
const PRINT_EVERY = 1000000
go sum_up("Amy", COUNT_TO, PRINT_EVERY, done)
go sum_up("Brian", COUNT_TO, PRINT_EVERY, done)
<- done
<- done
}
Result:
....
Amy working on: 7000000
Brian working on: 8000000
Amy working on: 8000000
Amy working on: 9000000
Brian working on: 9000000
Brian: 10000000
Amy: 10000000
Also if I add a function that just does a forever loop, that will block the entire process.
func dumb() {
for {
}
}
This blocks at some random point:
go dumb()
go sum_up("Amy", COUNT_TO, PRINT_EVERY, done)
go sum_up("Brian", COUNT_TO, PRINT_EVERY, done)
Well, let's say runtime.GOMAXPROCS is 1. The goroutines run concurrently one at a time. Go's scheduler just gives the upper hand to one of the spawned goroutines for a certain time, then to another, etc until all are finished.
So, you never know which goroutine is running at a given time, that's why you need to synchronize your variables. From your example, it's unlikely that sum(100) will run fully, then sum(200) will run fully, etc
The most probable is that one goroutine will do some iterations, then another will do some, then another again etc.
So, the overall is that they are not sequential, even if there is only one goroutine active at a time (GOMAXPROCS=1).
So, what's the advantage of using goroutines ? Plenty. It means that you can just do an operation in a goroutine because it is not crucial and continue the main program. Imagine an HTTP webserver. Treating each request in a goroutine is convenient because you do not have to care about queueing them and run them sequentially: you let Go's scheduler do the job.
Plus, sometimes goroutines are inactive, because you called time.Sleep, or they are waiting for an event, like receiving something for a channel. Go can see this and just executes other goroutines while some are in those idle states.
I know there are a handful of advantages I didn't present, but I don't know concurrency that much to tell you about them.
EDIT:
Related to your example code, if you add each iteration at the end of a channel, run that on one processor and print the content of the channel, you'll see that there is no context switching between goroutines: Each one runs sequentially after another one is done.
However, it is not a general rule and is not specified in the language. So, you should not rely on these results for drawing general conclusions.
#Akavall Try adding sleep after creating dumb goroutine, goruntime never executes sum_up goroutines.
From that it looks like go runtime spawns next go routines immediately, it might execute sum_up goroutine until go runtime schedules dumb() goroutine to run. Once dumb() is scheduled to run then go runtime won't schedule sum_up goroutines to run, as dumb runs for{}

Do we need a sleep() while running a forever process in Linux?

I have read that a forever process like daemon should run with a sleep() in their while(1) or for(;;) loop. They say, it is required because otherwise this process will always be in a run queue and the kernel will always run it. This will block the other process. I don't agree that it will block the other process completely. If there is a time slicing, then it will execute other process. But, certainly it will steal a time from others. Making a delay for other process since this process is always in the run state. By default, the Linux runs as a round-robin. The first task is swapd, then other tasks . This is a circular link list with first task as swapd(process-id is 0) and then other tasks. I believe this is still based as time sliced. A particular time for each process. These tasks are nothing but the process-descriptor. I believe this link list is maintained by the init process. Please do correct me here If I am wrong. Other question is if we need to give a sleep() then what should be its value? How can we determine the sleep value to get the best results?
If your program has useful things to do, don't throttle it. A program can move out of the run queue by doing blocking stuff like IO and waiting.
If you are writing a polling loop that can spin an arbitrary number of times you probably want to throttle it a bit with sleep because spinning too often has little value.
That said, polling loops are a means of last resort. Normally, programs perform useful work with every instruction, so they don't sleep at all.
Sleep is almost certainly the wrong solution.
Usually what you do it call a blocking function which wakes you up when there's something for you to do.
For example, if you're a network service you'd want to remain inactive until a request arrives.
In other words, the core of your daemon should not look like this:
while(1)
{
if (checkIfSomethingToDo())
doSomething();
else
sleep(1);
}
but rather a little like this:
while(1)
{
int ret = poll(fds, nfds, -1);
if (ret > 0)
doSomething();
}
Have the kernel put you to sleep until there's actual work to do. It's not hard to implement, you'd be a lot more efficient (not stealing CPU time from others, only to waste it doing no actual work) and your response latency will go down too.
A sleep forces the os to pass execution to another thread and therefore is helpfull, or at least fair. Start with sleep one. Should be ok.

What is the smart way for start parallel tasks in forked proccess via perl, linux and anyevent?

I have an issue with AnyEvent::Utils::fork_call. I m using fork_call, then doing some work, and after that i should end my fork_call, and start new parallel task.
I tried that:
fork_call {
# very important work
# start new parallel task
if (my $pid = fork) {
# other important and very long work
}
} sub {
# never reached this, while parallel task working
}
I suppouse that any event fork_call is waiting for all its childs to finish their jobs.
So how can I avoid this problem? Maybe I should get rid of parent process?
Any suggestions and advices are welcome.
Thank you.
I don't know if that suits your needs, but you can run next fork_call in a callback in first one. Something like this appears to work:
fork_call {
# Important work
} sub {
fork_call {
# other important work
} sub {
warn "done!";
}
};
Because second fork_call is used in first one's callback this means it forks and starts after "Important work" is done.
While not directly an answer to your question, doing any nontrivial amounts of processing in a forked child is error-prone and unportable. A generic way to avoid any and all such problems is to use AnyEvent::Fork (and/or AnyEvent::Fork::RPC, AnyEvent::Fork::Pool) to create worker processes. These modules create a new Perl process from scratch and use it to fork further worker processes. This avoids almost all problems with inheriting state from your parent, which might be the problem you are running into - it might especially explain why it works sometimes for you and sometimes not, depending on what other things were going on when the process was forked.

Resources