LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
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 04-06-2009, 08:38 PM   #1
CoderMan
Member
 
Registered: Jan 2009
Location: Gemini Capsule 25164
Distribution: Gentoo
Posts: 375
Blog Entries: 24

Rep: Reputation: 43
Question c system function in child thread


Hi. I wrote a curses app which used the "system" function to temporarily switch two an external program (so, as soon as the user quit the external program, he would be brought back to my application).

However, I recently split all the functionality of the app into two threads via the pthreads library. I needed to make the call to system from the second (child) thread (I don't know if it is technically considered a child thread...) But when I tried this odd things would happen: for example, if I tried to use system to open a bash prompt, the original app process would be turned into a stopped background job. (?)

I've been trying to accomplish the same thing with execl, but would appreciate any advice here. Execl, it seems, replaces the original process image. But if I use fork() with execl(), then somehow the input stream doesn't get completely passed to the new program as is the case with system.
 
Old 04-06-2009, 09:27 PM   #2
grunt547
Member
 
Registered: Nov 2006
Distribution: Slackware 12.2, Ubuntu 8.10
Posts: 30

Rep: Reputation: 15
The system() call makes the whole calling process wait until the command completes, meaning both threads are blocked. If execl() isn't working for you, you could try forking a second process, calling system() from the child, then exiting the child as soon as the command completes. This would allow your original process to continue while the new one runs.
 
Old 04-06-2009, 10:55 PM   #3
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
What's probably happening is the call to system creates a fork in the same process group as the original process. It sounds like the original process isn't in the foreground to start with, thereby causing the call to system to stop the entire process group until the session leader yields control of the terminal. There isn't much you can do about that while still having access to the terminal unless you fork, setpgid, and execvp instead of system.
Kevin Barry

On second thought, system might actually be calling setpgid and while bash steals foreground your console app is stuck in the background unable to perform terminal operations. Again, not much you can do about that; two things can't control the terminal at once.

Last edited by ta0kira; 04-06-2009 at 10:58 PM.
 
Old 04-08-2009, 06:16 PM   #4
CoderMan
Member
 
Registered: Jan 2009
Location: Gemini Capsule 25164
Distribution: Gentoo
Posts: 375
Blog Entries: 24

Original Poster
Rep: Reputation: 43
Solved!

I got this working. The issue was (as the previous posts mentioned) that the terminal can only have one process reading from the terminal at any given time.

According to the setpgid(2) man page (from the Linux programmer's manual):

Quote:
A session can have a controlling terminal. At any time, one (and only one) of the process groups in
the session can be the foreground process group for the terminal; the remaining process groups are in
the background. If a signal is generated from the terminal (e.g., typing the interrupt key to gener‐
ate SIGINT), that signal is sent to the foreground process group. (See termios(3) for a description
of the characters that generate signals.) Only the foreground process group may read(2) from the
terminal; if a background process group tries to read(2) from the terminal, then the group is sent a
SIGTSTP signal, which suspends it. The tcgetpgrp(3) and tcsetpgrp(3) functions are used to get/set
the foreground process group of the controlling terminal.
In my application there are two threads. One thread is in charge of taking input from the user through getch(). The other thread is in charge of (among other things) calling system(). So system creates the new process like it is supposed to, but the first thread (and thus the original process) continues running and eventually calls getchar(). Consequently, the original app process receives the SIGTSTP signal from the terminal, and becomes a stopped background job.

So, I could continue to use system(). All I had to do, though, was to implementing locking (with a pthread mutex) to ensure that before the second thread calls system(), the first thread is blocked. Then I released the block on the first thread immediately after the system() function has returned.

(Side note: With my specific implementation of the locking, I dealt with a small issue related to the second thread having trouble being able to function correctly, since the first thread has the mutex locked over 99% of the time. I fixed this by adding in a few milliseconds of nanosleep to the first thread's loop, to ensure that the second thread has some time to get the mutex locked itself. I thought I'd mention that in case somebody else ran into the same problem.)
 
Old 04-08-2009, 11:55 PM   #5
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Yes, I've always been amazed at how a few 10ms pauses here and there can keep a program running smoothly. Out of curiosity, why do you use the terminal for two different purposes in the same program?
Kevin Barry
 
Old 04-09-2009, 11:40 PM   #6
CoderMan
Member
 
Registered: Jan 2009
Location: Gemini Capsule 25164
Distribution: Gentoo
Posts: 375
Blog Entries: 24

Original Poster
Rep: Reputation: 43
Quote:
Originally Posted by ta0kira View Post
Yes, I've always been amazed at how a few 10ms pauses here and there can keep a program running smoothly. Out of curiosity, why do you use the terminal for two different purposes in the same program?
Kevin Barry
I'm writing this curses-based program launcher, and I want each major component displayed on the screen running in its own thread, so I can easily have cool things like complex animations, clocks, dynamic menus, etc. One thread is dedicated just to input, and it messages the other threads.

Its been challenging learning the pthreads lib (and all the associated problems) but I think it has already payed off in making several parts of the programming easier to finish and a lot more fun to write.
 
Old 04-10-2009, 06:41 AM   #7
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 808

Rep: Reputation: 178Reputation: 178
Quote:
Originally Posted by CoderMan View Post
One thread is dedicated just to input
In the long run, you might find it useful to have one thread dedicated just to output as well. If you do, it will probably be useful to use pty's, one pair per program launch. pty's aren't trivial, but they're not rocket science.

For a smallish project with goals that you can clearly see from here, you might not want to do this. But if this project could eventually grow in complexity beyond what you see now, this might be worth it.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
how can you pause child/parent processes in C and execute another function. expeliarmus Programming 5 08-06-2007 01:04 AM
Alternative to child in C...thread maybe? zaichik Programming 1 09-09-2005 08:34 PM
Assign memory in child function Jamesminh Programming 7 09-30-2004 02:47 AM
Main thread sending notification to child thread rajesh_b Programming 1 09-22-2004 09:15 AM
Perl exec function in linux (and system-function) nazula Programming 1 04-19-2004 12:21 PM


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

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration