ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm writing a program which use multiple threads.
Now, I'd need to print for each thread some info.
Basically, each thread loads some data and I'd want to print something like:
Code:
printf("Thread %d -> Data (%d/%d)", thread_num, cur_data, tot_data);
Each thread should have to overwrite its own line rather than create another one.
Carriage return usage should be ok but, in this case, each thread overwrites the line
getting a non-wanted behaviour.
How could I achieve this goal ?
I definitely prefer @EdGr's suggestion. Very specifically, here's what I would do:
Create an array of "messages," and an array (initialized to zero before any threads are started) of pid's. ("pid = process or thread-id")
Create a mutex which will control access to both of these, and make it available to all threads.
Each thread, upon initialization, (grabs the mutex and ...) finds a zero-slot in the pid array, puts its own pid into it, and remembers the index.
Each thread thereafter, upon wanting to update a message, (grabs the mutex and ...) stores the message into "its" chosen message-array slot (using "sprintf").
Finally, create another single thread which, (say ...) once per second, (grabs the mutex and ...), sends a "blank screen" sequence and then outputs all of the messages at once.
The (one ...) mutex first ensures that the threads will not "race" to claim their display slots. Then, it ensures that the display-update thread will never encounter an incomplete message. Finally, the presence of a display-update thread, also using this mutex, avoids visual chaos. Only this one thread actually performs any terminal output.
Last edited by sundialsvcs; 03-23-2024 at 08:08 PM.
Actually, I already thought a new thread but I was wondering whether a simple Ansi escape sequence can resolve the problem. Anyway the latter requires a mutex to properly work and I'd want to avoid because will cause a little bit slowing about threads parallelism. The new thread will have to simply composite an unique string with the data which are already in memory and print it with carriage return.
Thanks all for feedbacks.
Mark as solved.
If "every thread, independently," tries to perform I/O, the fully-asynchronous nature of "multitasking" inevitably results in visual chaos. After all, the thread or process could be pre-empted in the middle of trying to send a character sequence. It simply doesn't work.
In fact, this idea works generally. When "many threads or processes" need to read or write from a single physical resource, such as a disk file, the most-reliable method is to dedicate one thread or process, fed by (or, supplying) queues of some sort, to the task of "actually doing it."
yes, with other words (and in general): you need only one worker thread and all the other threads can collect and put the data into a common area/variable/array. This should be used in every case when the given "work" is not thread safe (like displaying those messages).
If "every thread, independently," tries to perform I/O, the fully-asynchronous nature of "multitasking" inevitably results in visual chaos. After all, the thread or process could be pre-empted in the middle of trying to send a character sequence. It simply doesn't work.
This is a solved problem. You treat stdout as a shared resource to which writes have to be synchronized. What that looks like, is that each thread locks the mutex before doing the printf, and unlocks it afterwards.
Honestly, the reason I didn’t spell this out is because I assumed I didn’t need to.
This is a solved problem. You treat stdout as a shared resource to which writes have to be synchronized. What that looks like, is that each thread locks the mutex before doing the printf, and unlocks it afterwards.
But if you also need to "position the cursor," in order to write the thread's output to a particular row on the terminal, the visual result might be "fairly schizophrenic." Hence the suggestion, in this case, to dedicate one thread to the task of "updating the display at periodic intervals." Much cleaner, and the display updates will be "steady, and 'fast enough.'" Plenty of ways to get it done.
This is a solved problem. You treat stdout as a shared resource to which writes have to be synchronized. What that looks like, is that each thread locks the mutex before doing the printf, and unlocks it afterwards.
Honestly, the reason I didn’t spell this out is because I assumed I didn’t need to.
No, I mean don't use mutex if you are not really need to do that. That adds an additional level of complexity and possibility to go into deadlock and other surprising situations. Better to have a dedicated thread for it.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.