LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-23-2024, 03:43 PM   #1
tuxuser1
Member
 
Registered: Nov 2021
Posts: 165

Rep: Reputation: Disabled
Printf in multithreading context


Hi,

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 ?

Regards

Last edited by tuxuser1; 03-23-2024 at 03:46 PM.
 
Old 03-23-2024, 05:25 PM   #2
EdGr
Member
 
Registered: Dec 2010
Location: California, USA
Distribution: I run my own OS
Posts: 998

Rep: Reputation: 470Reputation: 470Reputation: 470Reputation: 470Reputation: 470
Have each thread write an entry to an array. Print the entire array.
Ed
 
Old 03-23-2024, 06:07 PM   #3
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,226

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
Use ANSI sequences to move the cursor to specific rows.
 
Old 03-23-2024, 08:00 PM   #4
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941
I definitely prefer @EdGr's suggestion. Very specifically, here's what I would do:
  1. Create an array of "messages," and an array (initialized to zero before any threads are started) of pid's. ("pid = process or thread-id")
  2. Create a mutex which will control access to both of these, and make it available to all threads.
  3. 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.
  4. Each thread thereafter, upon wanting to update a message, (grabs the mutex and ...) stores the message into "its" chosen message-array slot (using "sprintf").
  5. 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.
 
Old 03-24-2024, 02:34 AM   #5
tuxuser1
Member
 
Registered: Nov 2021
Posts: 165

Original Poster
Rep: Reputation: Disabled
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.
 
Old 03-26-2024, 08:50 AM   #6
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941
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."
 
Old 03-26-2024, 10:25 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,855

Rep: Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311
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).
 
Old 04-02-2024, 03:45 PM   #8
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,226

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
Quote:
Originally Posted by sundialsvcs View Post
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.

Last edited by dugan; 04-02-2024 at 03:47 PM.
 
Old 04-02-2024, 08:10 PM   #9
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941
Quote:
Originally Posted by dugan View Post
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.
 
Old 04-03-2024, 01:24 AM   #10
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,855

Rep: Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311
Quote:
Originally Posted by dugan View Post
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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] printf $"Hello $var\n" vs. printf "Hello $var\n" -- not a typo. What is it? GrapefruiTgirl Programming 2 10-21-2010 08:21 AM
Multithreading is possible in linux ?. Which tool used for this? saira Linux - Software 1 03-24-2004 10:29 PM
How OpenMozix is used for multithreading in cluster computing in linux sabeen Red Hat 1 03-24-2004 10:25 PM
multithreading libraries Pres Programming 3 06-20-2003 03:27 AM
How is 'man 3 printf' different from 'man printf' ?? purpleburple Linux - General 3 09-23-2002 12:29 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration