I'm having problems, I need to make a program that make 9 child processes, after that I have to put a countdown of 3 seconds and make these 9 processes to wait for a signal from the father, after they receive this signal, every children should say what children he is (if he is the children #1, #2, #3, etc..., in order in which they were made).
What I've done is here, everything is OK, I think, until the part where I have to say as a children, what is my number, I don't have a clue how to do it, because each children is a different process, they don't share memory and the signal can't use arguments for that, by now I'm printing the PID on the function called "handler", but how can I print my number, as a Children?.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
void handler(int x);
int main() {
pid_t child[9];
pid_t child_pid;
for (int i = 0; i < 9; ++i) {
child_pid = fork();
child[i] = child_pid;
if (child_pid == 0)
break;
if (child_pid < 0) {
perror("fork()");
exit(EXIT_FAILURE);
}
}
if (child_pid == 0) {
signal(SIGUSR1, handler);
pause();
} else {
printf("Countdown:\n");
sleep(1);
printf("3\n");
sleep(1);
printf("2\n");
sleep(1);
printf("1\n");
sleep(1);
for (int i = 0; i < 9; i++)
kill(child[i], SIGUSR1);
waitpid(-1, NULL, 0);
}
return 0;
}
void handler(int sig) {
printf("This is Child #%d\n", getpid());
exit(0);
}
Create a global variable:
int my_number;
Then in your loop that creates the children, do:
if (child_pid == 0) {
my_number = i;
break;
}
Then you can use the variable in the handler:
void handler(int sig) {
printf("This is Child #%d\n", my_number);
exit(0);
}
Related
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...)
I have a function that is not the main function, A. This function simply iterates, say 1 to 1,000,000. At every X iteration, lets say 10,000, I want to run another function, but not stop the iteration. So it'd look something like this:
void iterate() {
for (int i = 0; i < 1000000; i++) {
i++;
if ((i%10000) == 0) {
// Spawn a process here
// This process should start, then
// the rest of the iterations should continue
// while the process is running
}
}
}
How would I do it?
This should work on POSIX compliant systems or using Cygwin on Windows.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
void func(void)
{
printf("Fork called\n");
}
void iterate(void)
{
pid_t pid;
int i;
for (i = 0; i < 1000000; i++) {
if (!(i % 10000)) {
pid = fork();
if (!pid) {
func();
exit(0);
}
}
}
wait(NULL);
}
int main(void)
{
iterate();
return 0;
}
fork() will start a child process. After the fork make you check that you are a child process and execute whatever you want. The wait() after the for loop will pause the parent process until the all sub processes finish executing.
Additional info about fork() and wait():
https://www.man7.org/linux/man-pages/man2/fork.2.html
https://www.man7.org/linux/man-pages/man2/wait.2.html
Here is the code that I have so far:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int value = 0;
void *runner(void *param);
int main(){
int pid;
pthread_t tid;
pthread_attr_t attr;
pid = fork();
if (pid == 0) {
pthread_attr_init(&attr);
pthread_create(&tid,&attr,runner,NULL);
pthread_join(tid,NULL);
printf("A: value = %d\n", value);
}
else if (pid > 0) {
wait(NULL);
printf("B: value = %d\n", value);
}
}
void *runner(void *param){
value = 5;
pthread_exit(0);
}
I have identified the child and parent processes but I am not sure how to make A and B print interleaved.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Im trying to create two children for each process(binary tree) and if n=3 the process tree structure should be like (1)->(2),(1)->(3),(2)->(4),(2)->(5).I have written a program where in i am able to create 2 processes for a prent process and 2 process for each child process but I want to provide a number n=number and create the processes based on the number passed in binary Tree format.
Here is my code:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int foo(const char *whoami) {
printf("I am a %s. My pid is:%d my ppid is %d\n", whoami, getpid(), getppid() );
return 1;
}
int func()
{
int pid = fork();
if (pid==0) {
foo("child");
int pid2 = fork();
if (pid2==0) {
foo("child");
exit(0);
}
else {
wait(NULL);
}
int pid3 = fork();
if (pid3==0) {
foo("child");
exit(0);
}
else {
wait(NULL);
}
exit(0);
}
else {
wait(NULL);
}
int pid1 = fork();
if (pid1==0) {
foo("child1");
int pid4 = fork();
if (pid4==0) {
foo("child");
exit(0);
}
else {
wait(NULL);
}
int pid5 = fork();
if (pid5==0) {
foo("child");
exit(0);
}
else {
wait(NULL);
}
exit(0);
}
else {
wait(NULL);
}
return 0;
}
int main()
{
foo("parent");
func();
return 0;
}
output :
I am a parent. My pid is:37 my ppid is 18
I am a child1. My pid is:38 my ppid is 37
I am a child2. My pid is:39 my ppid is 38
I am a child3. My pid is:40 my ppid is 38
I am a child4. My pid is:41 my ppid is 37
I am a child. My pid is:42 my ppid is 41
I am a child5. My pid is:43 my ppid is 41
As I assume that Raj understood fork() and wait() but did not yet get the concept of binary trees (and how to implement them using recursive functions) I made a small complete sample for this. It prevents the usage of fork() to make the binary tree/recursion concept more clear.
Putting it altogether:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
void foo()
{
printf("child process %d, (%d)->(%d)\n",
getpid(), getppid(), getpid());
}
/* creates child processes in binary tree manner.
*
* n ... number of tree nodes (child processes) to create
*/
void do_fork(int n)
{
if (n <= 0) return;
int n1 = n / 2;
int n2 = n - n1;
int pid1 = 0, pid2 = 0;
if (n1 >= 0) {
--n1;
pid1 = fork();
if (pid1 < 0) {
fprintf(stderr, "ERROR: fork failed in process %d!\n", getpid());
return;
}
if (pid1 == 0) {
foo();
do_fork(n1);
exit(0);
}
}
if (n2 >= 0) {
--n2;
pid2 = fork();
if (pid2 < 0) {
fprintf(stderr, "ERROR: fork failed in process %d!\n", getpid());
return;
}
if (pid2 == 0) {
foo();
do_fork(n2);
exit(0);
}
}
wait(NULL);
}
int main(int argc, char **argv)
{
int n = 3; /* number of binary tree nodes, might become input */
printf("parent process %d, children to create: %d\n", getpid(), n);
if (n) do_fork(n);
return 0;
}
I compiled and tested this with gcc on cygwin:
$ gcc -o test-bin-tree-fork test-bin-tree-fork.c
$ ./test-bin-tree-fork.exe
parent process 8628, children to create: 3
child process 13608, (8628)->(13608)
child process 7292, (8628)->(7292)
child process 8920, (7292)->(8920)
child process 14104, (7292)->(14104)
I have the test code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_t th_worker, th_worker2;
void * worker2(void *data) {
for(int i = 0; i< 1000000; i++){
printf("thread for worker2----%d\n", i);
usleep(500);
}
}
void * worker(void *data){
pthread_create(&th_worker2, NULL, worker2, data);
for(int i = 0; i< 100; i++){
printf("thread for worker-----%d\n", i);
usleep(500);
}
}
void join(pthread_t _th){
pthread_join(_th, NULL);
}
In main() function, If I call join(the_worker2):
int main() {
char* str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void*) str);
/* problem in here */
join(th_worker2);
return 1;
}
--> Segment Fault error
Else, i call:
join(the_worker);
join(th_worker2);
---> OK
Why have segment fault error in above case?
Thanks for help !!!
If you posted all your code, you have a race condition.
main is synchronized with the start of worker but not worker2.
That is, main is trying to join th_worker2 before worker has had a chance to invoke pthread_create and set up th_worker2 with a valid [non-null] value.
So, th_worker2 will be invalid until the second pthread_create completes, but that's already too late for main. It has already fetched th_worker2, which has a NULL value and main will segfault.
When you add the join for th_worker, it works because it guarantees synchronization and no race condition.
To achieve this guarantee without the join, have main do:
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
while (! th_worker2)
usleep(100);
/* problem in here */
join(th_worker2);
return 1;
}
An even better way to do this is to add an extra variable. With this, the first loop is not needed [but I've left it in]:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int worker_running;
pthread_t th_worker;
int worker2_running;
pthread_t th_worker2;
void *
worker2(void *data)
{
// tell main we're fully functional
worker2_running = 1;
for (int i = 0; i < 1000000; i++) {
printf("thread for worker2----%d\n", i);
usleep(500);
}
return NULL;
}
void *
worker(void *data)
{
// tell main we're fully functional
worker_running = 1;
pthread_create(&th_worker2, NULL, worker2, data);
for (int i = 0; i < 100; i++) {
printf("thread for worker-----%d\n", i);
usleep(500);
}
return NULL;
}
void
join(pthread_t _th)
{
pthread_join(_th, NULL);
}
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
// NOTE: this not necessarily needed as loop below is better
while (! th_worker2)
usleep(100);
// give worker2 enough time to completely start
while (! worker2_running)
usleep(100);
/* problem in here (not anymore!) */
join(th_worker2);
return 1;
}