As far as I know, Go runtime scheduler manages some number of OS Threads(probably more than GOMAXPROCS?) and Go routines by assigning Go routines to OS Threads continuously.
So this basically means that the execution of Go routines, including main goroutine , are managed by both of go scheduler and OS' thread scheudling.
Now here's my questions..
Does the execution of goroutine fully managed by OS' thread scheduling if I call runtime.LockOSThread() at the start of that goroutine?
Does the execution of non-Go thread also fully managed by OS' thread scheduling? In other words, if I create a non-Go Thread by CreateThread function (Windows), then the management non-Go Thread's execution is out of scope of Go's runtime scheduler?
What if I launch another goroutine with go func() in that non-Go Thread? How that non-Go Thread and goroutine's execution is managed?
Currently, I'm writing a program in Golang which runs a windows message loop in main() function of go program.
Most of the time it worked well, but sometimes the message loop get blocked and resumed after few seconds and then large amount of old messages get pumped.
(My another question: Windows Message Loop is getting blocked and resumed intermittently (golang))
I had no idea why it occurs, so I suspected main goroutine's OS Thread switch by go scheduler. So I added runtime.LockOSThread() at the start of main() function to ensure windows message loop always run in the same thread.
However, the problem still occured!
I still have no idea why it occurs, but I'm suspecting this is because of Go scheduler because the same logic written in Python 3.4 didn't make any problems like this.
So what I'm trying now is creating a new Windows Thread (non-Go Thread) by calling CreateThread(...) function, and running windows message loop in that thread.
But I'm curious that whether this approach is different with calling runtime.LockOSThread() in main goroutine running windows message loop from Go runtime scheduler's perspective.
So my question is, 'If I create a new non-Go Thread with CreateThread(...) function and run windows message loop in that thread, then does execution of that thread not affected by Go's runtime scheduler?'
Any helps or ideas will be greatly appreciated.
Thanks.
If you run a new OS thread using the CreateThread() routine, Go's scheduler will not touch the thread. However, you will then have to implement a way for that thread to communicate with Goroutines. You can't, for instance, call a Go method directly from the thread created by CreateThread(). Instead, you will have to use some C-based system to poll events from a Goroutine.
As an aside, if you want to run the loop from the main OS thread, you should call LockOSThread() in init() rather than in main(). See https://github.com/golang/go/wiki/LockOSThread:
func init() {
runtime.LockOSThread();
}
func main() {
// Run loop here.
}
Related
I'm trying to follow this tutorial/example here to setup my beanstalkd workers:
https://github.com/pjebs/beanstalkd-worker
My goal is to create a running go program that should listen to several beanstalkd tubes at once, and attempt to spawn workers on demand (and on available resources such as CPU, Memory etc). The workers actually simply a wrapper call for external workers (php, python, etc) to do certain jobs and catch back the returns.
The current issue is that when I try to run this program with go run test.go then the program would get stuck forever. It seems like I have made some mistake that cause my program to miss several wg.Done() that it should have called. I just cannot figure out where.
https://gist.github.com/yellow1912/afbd181a3dc2919f439d
(I'm a very beginner in Go, please feel free to criticize my code and suggest ways to improve)
I wanted to know how I can I make the io do something like a thread.join() wait for all tasks to finish.
io_type->post( strand->wrap(boost::bind &somemethod,ptr,parameter)));
In the above code if 4 threads were initially launched this would give work to the next available thread. However I want to know how I could actually wait for all the threads to finish work. Like we do with threads.join().
If this really needs to be done, then you could setup a mutex or critical section to stop your io handlers from processing messages off of the socket. This would need to be activated from another thread. But, more importantly...
Perhaps you should rethink your design. The problem with having the io wait for other threads to finish is that the io would then be unresponsive. In general, not a good idea. I suspect that most developers working on networking software would not even consider it. If you are receiving messages that are not ready to be processed yet due to other processing that is going on, then consider storing them in a queue and process them on a different thread when the other threads have signaled that they have completed their work.
assume I have a thread which is still running when the application is terminating
(This thread can not terminate because it waits for a Windows api call to return
and that can be long...)
What happens to the thread if the application is closed ?
Can it raise an exception (I'm under Delphi) ?
I'd say that an exception is very plausible. When you call Application.Terminate this will lead to the following sequence of events:
A call to PostQuitMessage.
Application.Terminated being set to True.
Application.Run returning.
System.Halt is called.
Exit procedures are run, specifically DoneApplication which will tear down Application and all components that it owns. Hmm, better hope your thread does not access anything owned by Application.
FinalizeUnits is called. Uh-oh. Memory manager is shut down, and lots more beside.
ExitProcess is called. Now your thread is killed.
Your thread will carry on running until the call to ExitProcess. If it executes any code at all that would be affected by the calls to DoneApplication and FinalizeUnits, then you should expect problems.
The windows form I am working on subscribes to Microsoft.Win32.SystemEvents.PowerModeChanged and on Suspend it runs the Close() method on the form. On Resume it runs the Run() function like it would on initial load. The problem is that when the computer is woken from sleep mode the PowerModeChanged event is triggered on a worker thread named ".Net SystemEvents" and when Run() is called it recreates the form on this worker thread instead of the main thread.
This form is a project I inherited from another developer and I am new to windows form programming. I am wondering if there is a better way to handle the sleep/wake process rather than closing the forms and recreating them on wake or a way to force the creation onto the main thread. Note: If I remove the code and have it do nothing when the computer is slept (suspended) and nothing when it wakes (resumes) then the program continues to work correctly (running on the main thread). Any help will be appreciated. Thanks all.
Capture the UI thread SynchronizationContext in a static field, and Post() on it to go back to the UI thread.
I am spawning few threads inside ioctl call to my driver. I am also assigning kernel affinity to my driver. I want to ensure one of the thread does not get scheduled out till a particular event is flagged by the other thread. Is there any way to not allow windows scheduler to context out my thread. Using _disable() may hang the system as event may take couple of seconds.
Environment is windows 7,64bit
Thanks,
What you are probably after is a spin lock. However this is probably a bad idea unless you can guarantee that your driver/application is always run on a multi-processor system, even then it is still very bad practice. On a single processor system if a thread spin locks then the other thread signalling the spin locked thread will never be scheduled and so can't signal your event. Spin locks are meant to be used sparingly and only when the lock is for a very short time, never a couple of seconds.
It sounds like you need to use an event or other signally mechanism to synchronise your threads and let the windows scheduler do its job. If you need to respond to an event very quickly then interrupts or a Deferred Procedure Call (DPC) could be used instead.