This is the code
pid_t pid;
srand(time(NULL));
for (int i=0; i < 2; i++)
{
pid = fork();
if (pid < 0)
{
std::cout<< "fork failed";
return -1;
}
else if (pid == 0)
{
std::cout<< "Process "<< i+1 << " ID: " << pid <<std::endl;
std::thread one (threadFunction, 0);
std::thread two (threadFunction, 1);
std::thread three (threadFunction, 2);
one.join();
two.join();
three.join();
}
else
{
wait (NULL);
exit(0);
}
}
The loop is supposed to create two different processes but whenever I run this the output pid is always 0. Does this mean it the same process
if pid == 0 your code is executing the child process. If pid is different than 0 your code execute the parent process
see section return value of the man
http://man7.org/linux/man-pages/man2/fork.2.html
you can find out the real pid of the child with function getpid
http://man7.org/linux/man-pages/man2/getpid.2.html
Related
I wrote a program which stops the time of a child process calling execvp(). The next task is to occasionally stop the child process for a given time and continue it.
pid_t child = fork();
if(child == 0){
// In child process
execvp(); // e.g. sleep 10
} else {
// In parent process
kill(child, SIGSTOP);
// Do stuff
kill(child, SIGCONT);
}
What i think is happening here is, that kill(child, SIGSTOP) is pausing the child process but not the execvp() process within it. Is there a way to get the pid of the execvp() process and stop it directly?
Edit example:
int main(int argsc, char *argv[]) {
int status;
// Fork for processB
pid_t processB = fork();
if (processB == 0) {
system("~/loop.sh");
} else {
for (;;) {
sleep(5);
kill(processB, SIGSTOP);
std::cout << "Should have stopped counting" << std::endl;
sleep(3);
kill(processB, SIGCONT);
// If loop process ended, exit watchDog
if (waitpid(processB, &status, WNOHANG) == processB)
_exit(1);
}
}
return 0;
}
Loop.sh
counter=0;
while :;
counter=$((counter+1));
do echo $counter;
sleep 1;
done
return 0;
I wanted to do this problem but I cannot take input message:
Create a program that does the following:
1.Create a parent and a child process
2.The parent process reads a number from keyboard and sends it to the child
3.The child calculates if the given number is prime or not and prints the result on screen
This is my code:
#include <iostream>
#include <unistd.h> // for fork()
#include <string.h> // for strerror()
#include <sys/wait.h>
#include <sys/types.h>
using namespace std;
bool isprime(int number);
int main()
{
int num;
pid_t pid;
int fd[2];
char buffer[100];
pipe(fd);
pid = fork();
//parent process
if (pid > 0)
{
cin>>num;
write(fd[1], &num, sizeof(num));
close(fd[1]);
int status;
//Do not check for errors here
wait(&status);
}
//child process
else if (pid == 0)
{
read(fd[0], buffer, 100);
close(fd[0]);
if (isprime(num))
{
cout<<"number is prime";
}
else
{
cout<<"number is not prime";
}
return EXIT_SUCCESS;
}
else
{
cout << "fork() failed (" << strerror(errno) << ")" << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
bool isprime(int number)
{
if (number < 2)
return false;
if (number == 2)
return true;
for (int i = 2; (i*i) <= number; i++)
{
// Take the rest of the division
if ((number % i) == 0)
return false;
}
return true;
}
this my result of run
Using a pipe along with fork is not that hard, but you must respect some rules:
each part should close the handle that it does not use. Not doing it is a key for future problems
starting from the fork, changes in one process are not reflected in the other one
Your code should become:
...
//parent process
if (pid > 0)
{
close(fd[0]); // close the part that only the other process will use
cin>>num;
write(fd[1], &num, sizeof(num));
close(fd[1]);
int status;
//Do not check for errors here
wait(&status);
}
//child process
else if (pid == 0)
{
close(fd[1]); // close the part used by the other process
read(fd[0], &num, sizeof(num)); // read into num what the parent has written
close(fd[0]);
...
In real world code, you should check that every read is successfull (both from cin and from the pipe...)
void* camera(void* arg)
{
int id = *(int *)arg;
cout << "please";
sleep(interval); // sleep interval seconds
int done = 0; /* 0 - not done; 1 - done */
long mysell = 0;
int s;
while(frame_cnt < 10){
if (rear == n - 1){// check if camera cache is full
sleep(interval);
}
else{
generate_frame_vector(8);
for (int i = 0; i < 8; i++){
rear++;
queue[rear] = frame_vector[i];
}
}
if(frame_cnt >= 10){
pthread_exit((void *) mysell);
}
}
}
int main(int argc, char* argv[]) { // Start
// Enter command, e.g: ./51234567 2 to run this program
if(argc == 2){ // if input is legal continue below with the rest of program execution
interval = atoi(argv[1]); // int interval stores the int value that will be used in sleep() later on
pthread_t threads;
int threadedid;
int rc; // rc is used to get the return value of pthread functions
rc = pthread_create(&threads, NULL, camera, (void *)&threadedid);
if (rc){
cout << "Error occured when creating the camera thread" << endl;
exit(-1);
}
}
else { // if input is not legal, then program will not fail to run and the message below displayed to the user
cerr << "Error occured because your argument is wrong; please use the format: './51234567 2' where 2 is the interval you want to use"
<< endl;
}
return 0;
}
Your program terminates immediately after the thread has been created because you don't wait for the thread to finish.
Add this somewhere before main() returns:
void* retval;
int r = pthread_join(threads, &retval);
if(r==0) // successfully joined the thread threads
else // failed to join the thread threads
I am trying to do something like this:
int main(int argc, char** argv)
{
bool foo = false;
//parse args, check if --foo is an arg, if so mark foo true
if (foo)
{
//child behavior
while (true) { std::cout << "child" << std::endl; sleep(1); }
}
else
{
//do some parent process stuff
pid_t pid = fork();
if(pid == 0) //spawn child
{
char* newArgv[argc+1];
for (int i = 0; i < argc; ++i) newArgv[i] = argv[i];
newArgv[argc] = "--foo"; //make child run child code
std::ostringstream oss;
oss << argv[0] << " >> foo.txt 2>&1"; //same binary but redir child output
execvp(out.str().c_str(), newArgv);
}
//more regular parent code
}
return 0;
}
So, basically, binary spawns itself with a new argument to run in a different way, and the output is redirected (ideally). Unfortunately, while this does spawn two processes, I seem to lose the output of the child and I'm not sure why?
What's wrong with the much simpler:
int main(int argc, char** argv) {
//do some parent process stuff
pid_t pid = fork();
if(pid == 0) //this is the child
{
//child behavior
while (true) { std::cout << "child" << std::endl; sleep(1); }
} else {
//more regular parent code
}
return 0;
}
You have to set filedescriptor 1 to point to foo.txt before calling execv. The child process will then use foo.txt as standard output:
fd_t f = open("foo.txt", O_WRONLY);
if (f != 1)
{
close(1);
dup2(f, 1);
close(f);
}
execv(...);
Any bugfixing in the code above is left as exercise for the reader. Bugfixing includes, but is not limited to, checking for errors returned from the function calls.
EDIT:
If you want standard error (fildescriptor 2) to go wherever standard output goes, you have to add this before execv:
close(2);
dup2(1, 2);
Here my code:
extern int errno;
pid_t system1(const char * command)
{
pid_t pid;
pid = fork();
cout<<"PID in child "<<(int)pid<<endl;
if (pid < 0) {
return pid;
} else if (pid == 0) {
execl("/bin/sh", "sh", "-c", command, (char*)NULL);
_exit(1);
}
int stat_val;
pid_t child_pid;
cout << "Hello1" << endl;
child_pid = wait(&stat_val);
cout << "child_pid = " <<(int)child_pid<< endl;//LINE 1
if(WIFEXITED(stat_val))
printf("Child has terminated with exit code %d\n", WIFEXITED(stat_val));
else
printf("Child has existed abnormally\n");
return child_pid;
}
int main( )
{
int pid_1 = system1("setup.csh &");;
struct stat status;
sleep(10);
cout<<"errno = "<<errno<<endl;
int i = kill(pid_1,0);
cout<<"Pid id = "<<pid_1<<endl;
cout<<"i === "<<i<<endl;
cout<<"errno = "<<errno<<endl;
if(errno == ESRCH)
{
cout<<"process does not exist";
}
else
{
cout<<"process exist"<<endl;
}
return 0;
}
In above code I am getting different PID of child at LINE 1 and PID of process setup.csh . Can anybody please help me out. I want to get PID of my process setup.csh.
I am looking other PID value using ps -u user | grep setup.csh in console.
When you run:
sh -c 'setup.csh &'
the original shell process forks another child process to run csh. The process hierarchy is:
YourProgram
sh -c 'setup.csh &'
csh setup.csh
There's no way to get this PID directly in the original program. Why don't you run setup.csh directly from your program, instead of going through the shell?
Actually, there's a way you can accomplish this. If you use the exec shell command, it runs the specified command in its own process, rather than forking a child:
system1('exec setup.csh &');