This is what says on http://invisible-island.net/ncurses/ncurses.faq.html#multithread
If you have a program which uses curses in more than one thread, you will almost certainly see odd behavior. That is because curses relies upon static variables for both input and output. Using one thread for input and other(s) for output cannot solve the problem, nor can extra screen updates help. This FAQ is not a tutorial on threaded programming.
Specifically, it mentions it is not safe even if input and output are done on separate threads. Would it be safe if we further use a mutex for the whole ncurses library so that at most one thread can be calling any ncurses function at a time? If not, what would be other cheap workarounds to use ncurses safely in multi-thread application?
I'm asking this question because I notice a real application often has its own event loop but relies on ncurses getch function to get keyboard input. But if the main thread is block waiting in its own event loop, then it has no chance to call getch. A seemingly applicable solution is to call getch in a different thread, which hasn't caused me a problem yet, but as what says above is actually not safe, and was verified by another user here. So I'm wondering what is the best way to merge getch into an application's own event loop.
I'm considering making getch non-blocking and waking up the main thread regularly (every 10-100 ms) to check if there is something to read. But this adds an additional delay between key events and makes the application less responsive. Also, I'm not sure if that would cause any problems with some ncurses internal delay such as ESCDELAY.
Another solution I'm considering is to poll stdin directly. But I guess ncurses should also be doing something like that and reading the same stream from two different places looks bad.
The text also mentions the "ncursest" or "ncursestw" libraries, but they seem to be less available, for example, if you are using a different language binding of curses. It would be great if there is a viable solution with the standard ncurses library.
Without the thread-support, you're out of luck for using curses functions in more than one thread. That's because most of the curses calls use static or global data. The getch function for instance calls refresh which can update the whole screen—using the global pointers curscr and stdscr. The difference in the thread-support configuration is that global values are converted to functions and mutex's added.
If you want to read stdin from a different thread and run curses in one thread, you probably can make that work by checking the file descriptor (i.e., 0) for pending activity and alerting the thread which runs curses to tell it to read data.
Related
I'm developing a game in pyglet, that scheduled by a simple text file like :
0:00:01;event1
0:00:02;event2
0:00:03;event3
The fact is that, among these events, some might be blocking (for instance event2 might consist in displaying instructions until a key is pressed). As a consequence, event3 might not be executed at the proper time (i.e., during the event2). For now, my strategy is to schedule one event after the other :
Execute the first event
Once the first event is finished, compute the remaining duration between the first and the second event (delta_duration)
Schedule the second event with a delay of delta_duration
... and so on
For now, I did not succeed in implementing properly a blocking event with this strategy. It seems that anything blocking the event_loop (like a sleep call during event2) is preventing even the graphical elements of event2 (text instructions) to be displayed. On the other hand, if I do not put any blocking routine (sleep) in the event2, I'm able to see the vertices, but the scheduler keeps on scheduling (!), and so the event3 comes too soon.
My question is : what would be a general strategy, in pyglet, to articulate non-blocking to blocking events ? More precisely, is it possible (desirable) to use multiple clocks for that purpose ? The pyglet documentation mentions that multiple clocks can be used but it is not very well explained.
I don't want a solution that is specific to my events example but, rather, general indications about the way to go.
It's really up to your program on what blocks. If you are using input from Python for the console window, then yes that will block because it's blocking execution of Python in general. If you have a label popup in the window that is waiting for input from an on_key_press window event, then that is completely different as it's not blocking the pyglet loop, it was scheduled within it.
If your event is a 20 second long math calculation, then that should probably be ran in a thread. You will probably have to separate the types of events in order to differentiate how they should be ran. It's hard to say because without a runnable example or sample of code, I am just guessing at your intentions.
Although it sounds more like you are wanting some sort of callback system. When execution of func1 is declared done, go to func2. There is nothing built into pyglet like this, you would have to have a clever use of scheduling. There are examples of this using pure python though. I personally use Twisted Deferred's for this.
I want to look for files with given extensions recursively from a given root directory and to display the number of files currently found in my GUI.
Since this kind of processing may be long, the GUI may be blocked.
I could just wait for the end of the processing and get the file count, but I am learning Qt (PyQt), so I see this as a training.
So I have read Qt doc:
When to Use Alternatives to Threads, and I don't think it's for me.
Then I read:
Choosing an Appropriate Approach, and I think my solution is the first one:
Run a new linear function within another thread, optionally with
progress updates during the run
But in this case you have 3 choices:
Qt provides different solutions:
Place the function in a reimplementation of QThread::run() and start the QThread. Emit signals to update progress. OR
Place the function in a reimplementation of QRunnable::run() and add the QRunnable to a QThreadPool. Write to a thread-safe variable
to update progress. OR
Run the function using QtConcurrent::run(). Write to a thread-safe variable to update progress.
Could you tell me how to choose the best one?
I have read some "solutions" but I'd like to understand why you should use one methodology instead of another one.
And also since I am looking for files, I may have a directory in which many files would match the search criteria. So it would mean lots of interruptions. Is there something special to keep in mind regarding this?
Thank you!
From what I know (hopefully more can chime in).
QThread offers support with signal interaction. For example, you'd be able to stop your concurrent function with a signal. Not sure how you'd do that with the other options, if at all.
Things to keep in mind: widgets all have to live in the main thread, but can communicate with other other threads via signals & slots.
Another quick thread on the topic w/ some decent bullet-points.
https://qt-project.org/forums/viewthread/50165/
Best of luck on your project, and welcome to Qt!
I'm using lua as the scripting language for handling events in my application, and I don't want to restrict users to writing short handlers - e.g. someone might want to have one handler run an infinite loop, and another handler would interrupt the first one. Obviously, lua doesn't directly support such behavior, so I'm looking for workarounds.
First of all, I'd like to avoid modifying the engine. Is it possible to set up a debug hook that would yield once the state has reached its quota? Judging by the documentation, it shouldn't be hard at all, but I don't know if there are any caveats to this.
And second, can I use lua_close to terminate a thread as I would in actual multithreading?
I've done something similar in the past. Its completely possible to multi-thread on separate Lua states. Be sure to take a look at luaL_lock() and luaL_unlock() (plus associated setup/cleanup), as you will no doubt need this setup (a simple mutex should do the trick).
After that, it should be a fairly simple matter of creating a lock/wait/interrupt API for your handlers.
I am writing a Lua script that uses a library to access a hardware device with buttons. I register a callback function to handle the button presses. The code looks like:
globalvar = {}
function buttonCallback(buttonId)
...accessing globalvar
end
device.RegisterButtonCallback("buttonCallback")
while true do
end
This works.
Now I want to update the globalvar not only at a button presses but also at 1 minute intervals. Since I will need to access a network resource anyway I plan on using the socket.select call to get the 1 minute interval.
#require "socket"
globalvar = {}
function buttonCallback(buttonId)
...access globalvar
end
device.RegisterButtonCallback("buttonCallback")
while true do
socket.select(nil, nil, 60) -- wait 60 seconds
...access network
...access globalvar
end
Now I am concerned about the concurrent access of the globalvar. How can I prevent race conditions here? Most sources on multithreading in Lua advise to use continuations in cooperative scheduling but I don't see how that could be applied in my case.
Assuming the library you're using is creating another thread behind the scenes, and your only concern is about accessing globalvar from within the callback, you could avoid it by writing to a pipe in the callback, and reading from it in your select loop. In other words, use a standard POSIX-style pipe to communicate the callback back to the main thread. This is a fairly common technique when dealing with e.g. POSIX signals.
Lua is not thread-safe within a particular lua_State instance. You cannot modify a global variable from one thread while another thread is doing something else with that Lua instance. You most certainly cannot be executing two separate scripts on the same instance.
Thread safety is something you have to do outside of Lua. You cannot have the C/C++ thread that detects the button press actually call Lua code directly. It must send that data to the main thread via some thread-safe mechanism, where it will call the Lua script for them.
So I took a deep dive into the Lua books and online documentation, and contacted the author of the device driver. As the answers already indicated, it takes much more than anticipated to handle the button callbacks safely.
My approach now is to write the device driver myself and use sockets as communication channel between the device and the Lua script.
My initial approach was to use continuations as this is advocated as the Lua "replacement" for multithreading but when I read the programming in Lua book, it turns out that in order to prevent busy waits, it uses the socket.select (!). This increased my feeling that a socket-based approach is good, especially since I also need sockets for internet access in my script.
I'm using 3.9.7 cURL library to download files from the internet, so I created a dynamic bibioteca of viculo. dll written in C using VC + + 6.0 the problem is that when either I call my function from within my vb6 application window locks and unlocks only after you have downloaded the file how do I solve this problem?
The problem is that when you call the function from your DLL, it "blocks" your app's execution until it gets finished. Basically, execution goes from the piece of code that makes the function call, to the code inside of the function call, and then only comes back to the next line after the function call after the code inside of the function has finished running. In fact, that's how all function calls work. You can see this for yourself by single-stepping through your code in the VB 6 development environment.
You don't normally notice this because the code inside of a function being called doesn't take very long to execute before control is returned to the caller. But in this case, since the function you're calling from the DLL is doing a lot of processing, it takes a while to execute, so it "blocks" the execution of your application's code for quite a while.
This is a good general explanation for the reason why your application window appears to be frozen. A bit more technically, it's because the message pump that is responsible for processing user interaction with on-screen elements is not running (it's part of your code that has been temporarily suspended until the function that you called finishes processing). This is a bit more difficult for a VB programmer to appreciate, since none of this nitty-gritty stuff is exposed in the world of VB. It's all happening behind the scenes, just like it is in a C program, but you don't normally have to deal with any of it. Occasionally, though, the abstraction leaks, and the nitty-gritty rears its ugly head. This is one of those cases.
The correct solution to this general problem, as others have hinted at, is to run lengthy operations on a background thread. This leaves your main thread (right now, the only one you have, the one your application is running on) free to continue processing user input, while the other thread can process the data and return that processed data to the main thread when it is finished. Of course, computers can't actually do more than one thing at a time, but the magic of the operating system rapidly switching between one task and another means that you can simulate this. The mechanism for doing so involves threads.
The catch comes in the fact that the VB 6 environment does not have any type of support for creating multiple threads. You only get one thread, and that's the main thread that your application runs on. If you freeze execution of that one, even temporarily, your application freezes—as you've already found out.
However, if you're already writing a C++ DLL, there's no reason you can't create multiple threads in a VB 6 app. You just have to handle everything yourself as if you were using another lower-level language like C++. Run the C++ code on a background thread, and only return its results to the main thread when it is completely finished. In the mean time, your main thread is free.
This is still quite a bit of work, though, especially if you're inexperienced when it comes to Win32 programming and the issues surrounding multiple threads. It might be easier to find a different library that supports asynchronous function calls out-of-the-box. Antagony suggests using VB's AsyncRead method. That is probably a good option; as Karl Peterson says in the linked article, it keeps everything in pure VB 6 code, which can be a real time saver as well as a boon to future maintenance programmers. The only problem is that you'll still have to process the data somehow once you obtain it. And if that's slow, you're right back where you started from…
Check out this article, which demonstrates how to asynchronously transfer large files using a little-known method in user controls.