Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

child_process.fork and child_process.exec do not work together. #10412

Closed
JMishou opened this issue Dec 22, 2016 · 4 comments
Closed

child_process.fork and child_process.exec do not work together. #10412

JMishou opened this issue Dec 22, 2016 · 4 comments
Labels
child_process Issues and PRs related to the child_process subsystem.

Comments

@JMishou
Copy link

JMishou commented Dec 22, 2016

var child_process = require('child_process');

var failed_wifi_reconnect_attempts = 0;

var checkWiFi = setInterval(WiFiCheck, 10000);

function WiFiCheck(){
    child = child_process.exec('ping -c 1 192.168.0.1', function(error, stdout, stderr){
        if(error) {
            console.log("Offline - Attempting to bring up wlan0")
            child_process.exec('ifup --force wlan0',function(error, stdout, stderr){
                console.log("error: " + error);
                console.log("stdout: " + stdout);
                console.log("stderr: " + stderr);
                if(error || stderr !== ""){
                    failed_wifi_reconnect_attempts++;
                    console.log("Failed to bring up wlan0\n" + stderr);
                    if (failed_wifi_reconnect_attempts == 5){
                        child_process.exec('shutdown -r now',function(error, stdout, stderr){
                            console.log(stdout);                        
                        });
                    }
                }
                else{
                    console.log("wlan0 back online");
                }
            });
        }
        else {
            console.log("Online")
        }
    });
}

Version: 4.5.0
Platform: Raspberry Pi Zero Linux 4.4.21+ #911 armv6l GNU/Linux
Subsystem: Raspian Jesse Lite

I have created a test script to check and restore a wifi connection on the raspberry pi. It works fine when tested by itself. However when I add it to the application that I want it to be integrated with it fails to execute. The issue seems to be that I have a forked process also running from the child_process library. If I remove the fork from the main app and leave the exec code it again works as it did in the test script.

@julianduque julianduque added the child_process Issues and PRs related to the child_process subsystem. label Dec 22, 2016
@sam-github
Copy link
Contributor

Do you have a standalone reproduction?

Or at least, can you describe

when I add it to the application that I want it to be integrated with it fails to execute

In what way does it fail?

child process share no state in node.js, this is very unlikely to be a node bug.

Whatever is happeing is likely either a bug in your code, or possibly something android specific relating to how those processes run and interact. Does your system limit the number of concurring child processes you can run?

@JMishou
Copy link
Author

JMishou commented Dec 22, 2016

When the exec get called while the active fork is running every process immediately goes defunct. In the output below the main process is 1365, the forked process is 1371, all other processes are attempts to run exec.

I am running linux so android should have nothing to do with this issue. I don't believe that there is any child process limit, I have executed several fork bombs to test the raspberry pi's watchdog timer and it seems that it can take thousands of processes before crashing.

4 S     0  1365  1361 25  80   0 - 33082 -      pts/0    00:00:12 node
4 S     0  1371  1365 53  80   0 - 30495 -      pts/0    00:00:22 node
0 Z     0  1388  1365  0  80   0 -     0 -      pts/0    00:00:00 sh <defunct>
0 Z     0  1390  1365  0  80   0 -     0 -      pts/0    00:00:00 sh <defunct>
0 Z     0  1396  1365  0  80   0 -     0 -      pts/0    00:00:00 sh <defunct>
0 Z     0  1411  1365  0  80   0 -     0 -      pts/0    00:00:00 sh <defunct>

@sam-github
Copy link
Contributor

I am running linux so android should have nothing to do with this issue.

OK, then please provide a standalone repro on non-Android Linux.

Interestingly, ps listing above shows 4 shell children waiting to be reaped by their parent node process (and one node child, presumably the fork), but you only have 3 calls to exec in your example code. Any ideas on why that is?

I suggest you use execFile() to eliminate the intermediary shell, it will at least be more efficient.

@JMishou
Copy link
Author

JMishou commented Dec 22, 2016

var checkWiFi = setInterval(WiFiCheck, 10000); - this is the reason for multiple processes. Ultimately it will be called once every 5 minutes but for now I am calling it every 10 seconds for testing. Each time exec is called the process does not execute.

So I have a working standalone below. Now I am even more confused as to what is causing the exec commands to fail. Anyway I guess this is an issue with my code and not an issue with the child_process library so I'll close the issue. If you have any other suggestions though please feel free to reply.

master.js

var fork = require('child_process').fork;
var exec = require('child_process').exec;
var oledHandler = fork('./oled-handler.js');

oledHandler.on('message', function(response) {
  console.log(response);
});

var oledCnt = 0;
var oledInterval = setInterval(updateScreen, 2000);

var failed_wifi_reconnect_attempts = 0;
var checkWiFi = setInterval(WiFiCheck, 10000);


function updateScreen(){
	
	//oled.clearDisplay(false);
	if (oledCnt) {
        oledHandler.send("1234");
        oledCnt = 0;
	}		
	else {
        oledHandler.send("5678");
        oledCnt = 1;
	}
    
}

function WiFiCheck(){
	child = exec('ping -c 1 192.168.0.1', function(error, stdout, stderr){
		if(error) {
			console.log("Offline - Attempting to bring up wlan0")
			exec('ifup --force wlan0',function(error, stdout, stderr){
				console.log("error: " + error);
				console.log("stdout: " + stdout);
				console.log("stderr: " + stderr);
				if(error || stderr !== ""){
					failed_wifi_reconnect_attempts++;
					console.log("Failed to bring up wlan0\n" + stderr);
					if (failed_wifi_reconnect_attempts == 5){
						exec('shutdown -r now',function(error, stdout, stderr){
							console.log(stdout);						
						});
					}
				}
				else{
					console.log("wlan0 back online");
				}
			});
		}
		else {
			console.log("Online")
		}
	});
	console.log(child.pid);
}

oled-handler.js

var i2c = require('i2c-bus');
var i2cBus = i2c.open(1, function (err) {  if (err) throw err; });
var oled = require('oled-i2c-bus');
var font = require('oled-font-5x7');


var oledOpts = {
  width: 128,
  height: 64,
  address: 0x3C
};

var oled = new oled(i2cBus, oledOpts);

process.on('message', function(msg) {
    oledMessage(msg);
});

function oledMessage(msg){
	oled.clearDisplay(false);
	oled.setCursor(1, 1);
	oled.writeString(font, 2, msg, 1, true);
}

@JMishou JMishou closed this as completed Dec 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
child_process Issues and PRs related to the child_process subsystem.
Projects
None yet
Development

No branches or pull requests

3 participants