LinuxQuestions.org
Visit the LQ Articles and Editorials section
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-04-2010, 04:43 AM   #1
eryn
Member
 
Registered: Jul 2009
Posts: 43

Rep: Reputation: 15
Sequencing problem with raising a signal method


Hello all,

I am encountering with a problem here and any help would be very much appreciated.

I was trying to program using fork(). The objective of this code is to
1. I am activating a process A - SubSuctionMotors.
2. Process A is going to stop with either of this condition
a) Switch is activated - swret=1
b) Time allowed has expired
3. Stop the process A.

*Process A is running a motor.

Now, let's see the code.

Code:
void usrl_handler( int sig_num )
{
	printf( "Time out(%d), signal received to terminate motor\n", getpid() );
	SubSuctionMotors (0);

} 

int SubFrameVertical ()
{

	int 	swret;
	int 	rc=0;
	int 	timeOut=0;
	pid_t ret;
	int role=-1; 
	    			
	
	ret = fork();
			
	if (ret>0) { 	/*Parent Context*/

	printf( "Parent: This is the parent process (pid %d)\n", getpid() );
	SubSuctionMotors (1);      /*Motor is activated and running.*/
	signal ( SIGUSR1, usrl_handler );
			
	role = 0; 
	
	swret=CheckSwitch(0);      /*Command to check if switch is activated.*/
	while(swret==0)
	{
	    swret=CheckSwitch(0);    /*while loop to continuously check if switch is activated, loop will exit if switch is activated (swret=1).*/
	}
        SubSuctionMotors (0);     /*Stop motor running.*/

	}

	else if (ret == 0) { 	/*Child Context*/
			
	printf( "Child: This is the child process (pid %d)\n", getpid() );
			
	role = 1; 
			
	sleep ( 2 );       /*Start counting time when motor start running, after 2 second, motor should be stopped. This is an additional condition that we add in case the switch did not being activated to protect our application.*/

	printf( "Child: Time Out, Sending SIGUSR1 to pid%d\n", getppid() );
	kill( getppid(), SIGUSR1 );
	}

	SubSuctionMotors (0);

       
        return rc; 									

}
We tried to compile the code and run it.
Now, our problem is
1. We purposely force the switch to be inactive to test the child process (timer), whether after 2 seconds the motor stop. It turns out to be successful in first few attempts. After some while, the program hang, nothing is executed anymore and the program is not exit or terminated. What can cause the program to hang?

2. We tried to stop motor by switch activation (if the switch is to be successfully activated, the time it takes will always be shorter than the timer allowed time). However, the program did not seems like noticing the switch has been activated, and it just stop the motor according to timer. Why it behave this way?

Thank you very much for your help.
 
Old 03-05-2010, 04:23 AM   #2
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Wheezy (Fluxbox WM)
Posts: 1,363
Blog Entries: 52

Rep: Reputation: 353Reputation: 353Reputation: 353Reputation: 353
Quote:
We purposely force the switch to be inactive to test the child process (timer), whether after 2 seconds the motor stop. It turns out to be successful in first few attempts. After some while, the program hang, nothing is executed anymore and the program is not exit or terminated. What can cause the program to hang?
It isn't clear how the parent task is meant to terminate if the switch is forced to be inactive? It receives the signal, but doesn't do anything with it.

Quote:
We tried to stop motor by switch activation (if the switch is to be successfully activated, the time it takes will always be shorter than the timer allowed time). However, the program did not seems like noticing the switch has been activated, and it just stop the motor according to timer. Why it behave this way?
Possibly the parent task had already exited. Have you tested that the CheckSwitch code works as you expect?

It is also not a good idea to have a busy loop (the check switch loop) that contains no waits or delays. At least add in a small sleep (eg a few milliseconds, or whatever is appropriate given the effect of the motor).

You also need to be careful about calling printf (and anything else that would make a system call) inside an interrupt handler. Most of these are unsafe (meaning that there is the risk of crashes or worse).

The easiest method is for the interrupt hander to just set a flag variable, which the main loop can monitor and exit normally (stopping the motor as it does so).

Last edited by neonsignal; 03-05-2010 at 04:25 AM.
 
Old 03-08-2010, 09:24 PM   #3
eryn
Member
 
Registered: Jul 2009
Posts: 43

Original Poster
Rep: Reputation: 15
To neonsignal,

I am not really clear of this statement
Quote:
It isn't clear how the parent task is meant to terminate if the switch is forced to be inactive? It receives the signal, but doesn't do anything with it.
What we actually want the sequence to be is as following:
a) motor start running with function SubSuctionMotors(1)
b) switch signal is read continuously with the loop while (swret==0),when the switch is activated, swret=1, and exit the loop. Motor is then stop by SubSuctionMotors(0) and also exit parent process.
c) child process start at the same time when motor start to run. It start to count time with sleep(2). In this interval of time, if no switch activation is detected, when 2 seconds is over, function SubSuctionMotors(0) in the child process is used to stop motor from running any more. Child process exit and send signal to parent to tell parent to exit also.

Did our code right for this sequence?

Quote:
Have you tested that the CheckSwitch code works as you expect?
The CheckSwitch code is definitely works, we tried it out before many times and all works just well.

Quote:
The easiest method is for the interrupt hander to just set a flag variable, which the main loop can monitor and exit normally (stopping the motor as it does so).
Main loop in this case means?
 
Old 03-09-2010, 12:24 AM   #4
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Wheezy (Fluxbox WM)
Posts: 1,363
Blog Entries: 52

Rep: Reputation: 353Reputation: 353Reputation: 353Reputation: 353
Quote:
Child process exit and send signal to parent to tell parent to exit also.
A signal does not abort a process unless you do it explicitly. This might be confusing at first, because unhandled signals default to abort; however, if you handle the signal, then all it does is run the signal handler function.

This means that no matter which of your processes finishes first, the other will be left running (which may lead to some confusion).

Quote:
Main loop in this case means?
By main loop I mean the switch testing loop in the parent thread.

Incidentally, what does the check switch code look like?
 
Old 03-09-2010, 03:24 AM   #5
eryn
Member
 
Registered: Jul 2009
Posts: 43

Original Poster
Rep: Reputation: 15
To neonsignal,

I just found out the solution to exit the child process as well as the parent process. It is all to be coded in handler function.

This is my code. I hope my code is stable (not hiding any risk of crash or buffer overflow).
Code:
void usrl_handler( int sig_num )
{
	printf( "Time out(%d), signal received to terminate motor\n", getpid() );
	SubSuctionMotors (0);
	exit(0); 
}

int SubFrameVertical (int updown)
{

	int 	dir;
	int 	swret;
	pid_t ret;
	int role=-1; 
	    			
	ret = fork();
			
	if (ret>0) { 	/*Parent Context*/

	printf( "Parent: This is the parent process (pid %d)\n", getpid() );
	SubSuctionMotors (1);
		
	signal ( SIGUSR1, usrl_handler );
			
	role = 0; 
	if (returnresult >0) SendStatus();
        else printf("Connection Fail\n");

	swret=CheckSwitch(0);
	while(swret==0)
	{
	    swret=CheckSwitch(0);
	}
        SubSuctionMotors (0);
	
        }

	else if (ret == 0) { 	/*Child Context*/
			
	printf( "Child: This is the child process (pid %d)\n", getpid() );
			
	role = 1; 
			
	sleep ( 2 );

	printf( "Child: Time Out, Sending SIGUSR1 to pid%d\n", getppid() );
	kill( getppid(), SIGUSR1 );
	}

	SubSuctionMotors (0);
	
        if (returnresult >0) SendStatus();
        else printf("Connection Fail\n");

	return rc;										

}
I have add in "exit(0)" in the usrl_handler. This settled my problem and get my sequence right.

However, I think I still encountering with problem of running out of memory after executing this the child code for a few times (this means switch is never being activated and child process--time out take turn to stop motor). Someone suggested that I should just pause the program when time out happen and wait for instruction from user. I am currently studying this problem. Any help or idea will be very welcomed and appreciated.
 
  


Reply

Tags
fork, signal, timer


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
bash array sequencing dbnor Linux - General 1 07-14-2008 10:13 AM
permutation combinations---sequencing abhattacharya Programming 3 08-14-2007 12:51 AM
Software for MIDI, sequencing and notation ... statguy Slackware 2 10-30-2004 11:21 AM
FC2: Wrong sequencing of network cards Schlabbl Linux - Hardware 4 09-02-2004 03:09 AM
Audio / Sequencing software, any suggestions? lucastic Linux - Software 3 01-02-2004 11:13 PM


All times are GMT -5. The time now is 05:24 AM.

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