This is is the program to Print Process ID and Parent Process ID's in C using Minix. I'm trying to compile the test code below this code to return the ID's but it isn't compiling. Any help would be appreciated.
//Program to print its Process ID, Parent Process ID
#include <stdio.h>
#include "pm.h" // for various global variables
#include "mproc.h" // for process table mproc
int do_printppids(void)
{
int idx = m_in.m1_i1;
int n = m_in.m1_i2;
while(n > 0 )
{
int pid = mproc[idx].mp_pid;
if(pid)
{
int parent = mproc[mproc[idx].mp_parent].mp_pid;
printf("proc: %sn", mproc[idx].mp_name);
printf("Pid: %d, PPid %dn", pid, parent);
n++;
}
else
{
n = 0;
}
idx++;
}
return 1;
}
This is my test class to try and return the Process ID and Parent Process IDs, but it isn't compiling in Minix.
#include <lib.h> // provides _syscall and message
#include <stdio.h>
#include <stdlib.h> // provides atoi
int main(void) {
message m; // Minix uses message to pass parameters to a system call
m_in.m1_i1 = 0;
m_in.m1_i2 = 10;
_syscall(PM_PROC_NR, PRINTPPIDS, &m);
}
Literally make sure to update and save all files before running Make Service + Install and then recompile the test class. Spent 4 hours staring pointlessly at my code because of it sigh
Related
I'm trying to figure out how the following program i wrote for a raspberry pi with led matrix works.
The program is supposed to have a child process forked by the main process light up the LED from 0,0 -0,8 in first iteration for num=0. But instead, the LEDs light up randomly in the 0th column.
Example : in 0th column 0,6,4,5,2,3,1
in 1st column 0,6,5,4,2,3,1
and so on till 8th column.
I'm confused as to why the "main" for loop controlling the rows runs randomly ,but the second loop controlling the columns works in an orderly increasing fashion.
What am I missing in the working of fork together with a for loop?
From the output I can only guess that the parent is somehow creating random child processes all at once that are calling function2 with their randomized num argument.
<header files>
function1
{ creates a delay of a second through calculations }
function2(n)
{ for(int i = 0; i<=8 ;i++)
function1;
printf("LED(%d,%d)\n",n,i);
}
main()
{
for(int num = 0; num <=7; num++)
{
pid_t pid = fork();
if (pid ==0)
{ function2(num); }
}
for (int num =0; num <= 7; num++)
{ wait(NULL);}
}
Father and child processes do run concurrently, and it is not predictable which process is running at what time.
From a first inspection you have a loop that starts from the father process and creates 8 child processes, that on their hand each creates other child processes! You should terminate the child process after calling the function2, otherwise the child processes will create other processes.
I think the solution to your problem is something like this:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void function1() {
//0.5 seconds sleep
usleep(500000);
}
void function2(int n) {
for(int i = 0; i <= 8; i++) {
function1();
printf("LED(%d,%d)\n", n, i);
}
}
int main()
{
pid_t pid;
for(int num = 0; num <= 7; num++) {
pid = fork();
if (pid == 0) {
function2(num);
exit(0);
}
}
for (int num = 0; num <= 7; num++){
wait(NULL);
}
return 0;
}
Please for future questions please post a Minimal, Complete, and Verifiable example.
The code could also have a concurrency problem, I don't think the printf is an atomic function, so a semaphore may be necessary to avoid having multiple processes calling the printf.
Another note is that a check should be fork() to check if the child process was successfully generated.
I'm working on Minix 3.
I'm implementing a new system call called do_identify that returns either the id of the current process or the parent process. Here's the definition of the system call under /usr/src/servers/pm/misc.c and it's library, which I named it identifylib.h, under /usr/include:
Definition:
PUBLIC int do_identify()
{
int identifier = m_in.m1_i1;
if(identifier == 1)
{
printf("Current Process ID = %d\n", getpid());
return getpid();
}
else
{
printf("Parent Process ID = %d\n", getppid());
return getppid();
}
}
Library:
#include <lib.h>
#include <unistd.h>
PUBLIC int identify (int process)
{
message m;
m.m1_i1 = process;
return ( _syscall(PM_PROC_NR, IDENTIFY, &m) );
}
Now, when I test it, i get the following error:
undefined reference to getppid
Am I invoking incorrectly this function? or Am I not supposed to invoke this function within the system call? I don't know what it is supposed to mean on minix.
Here is the test file: test_id.c
#include <identifylib.h>
int main(void)
{
printf("Process ID = %d\n" identify(1));
return 0;
}
I would like to limit the execution of a function in pure C, without stopping the whole program.
I believe the closest thing on stackoverflow.com to this was on the last comment of this thread: How to limit the execution time of a function in C/POSIX?
There was some talk of using setjmp and longjm placed after the function to limit in time, but the thread died.
Is there anyone that knows if this is indeed possible?
Cheers
I can see two options, first one check the time every few lines of code and return if it's too much, but I don't think it's a good idea.
Second, you could use threads. Run two functions at the same time, one timing the other, if the time is too big then it kills the first one. Now I'm pretty sure that windows and Linux have different libraries to create threads so you could try and use a library that works across all platforms like this one maybe http://openmp.org/wp/.
I'm not too familiar with that library and threads in general but I hope it helps
Though it could be of service to post my solution. It is a combination of this post http://cboard.cprogramming.com/c-programming/148363-limit-execution-time-function.html, and the IPC TPL example found here: https://github.com/troydhanson/tpl/blob/master/doc/examples.txt.
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stdbool.h>
#include <string.h>
#include "tpl.h"
//This example contains two different parts:
//1) The alarm is a execution timer for the function doWork
//2) There is a need, that if the execution exits correctly, that the chid value of i, that we are modifying be passes
typedef struct TEST_STRUCT
{
int i;
double sum;
} testStruct;
int doWork(testStruct * ts)
{
int y;
for(y=0; y<3; y++)
{
sleep(1);
printf("Working: %d\n", ts->i);
ts->i++;
ts->sum += (double)ts->i;
}
return 0;
}
int main()
{
testStruct * ts = (testStruct *)(calloc(1, sizeof(testStruct)));
ts->i = 7;
ts->sum = 4.0;
tpl_node *tn;
int fd[2];
pipe(fd);
int y;
for(y=0; y<10; y++)
{
pid_t childPID = fork();
if (childPID==0)
{
unsigned secsLeft;
alarm(10);
doWork(ts);
printf("\t->%d\n", ts->i);
printf("\t->%p\n", (void*) &ts->i);
tn = tpl_map("S(if)", ts);
tpl_pack( tn, 0 );
tpl_dump( tn, TPL_FD, fd[1]);
tpl_free( tn );
secsLeft = alarm(0);
exit(0);
}
else
{
//IMPORTANT TO PUT IT HERE: In case the buffer is too big, TPL_DUMP will wait until it can send another and hang
tn = tpl_map( "S(if)", ts );
tpl_load( tn, TPL_FD, fd[0]);
int status;
wait(&status);
if(WIFSIGNALED(status))
{
// child was interrupted
if (WTERMSIG(status) == SIGALRM)
{
printf("Interrupted\n");
// child interrupted by alarm signal
}
else
{
printf("Should not happend\n");
// child interrupted by another signal
}
}
else
{
tpl_unpack(tn,0);
tpl_free( tn );
printf("\t->%d\n", ts->i);
printf("\t->%p\n", (void*) &ts->i);
printf("Success\n");
}
}
}
return 0;
}
Basically, we fork the program, where the child performs a task and the parent waits for the child to finish. The child contains an alarm, that if true signals the parent that it existed in that manner. If it completes (as this example shows), the child sends the object function to the parent as a TPL buffer.
I am trying to print out the Fobonacci sequence according to how many numbers of it the user would like. I.e. if the user inputs 5, the output will be 1,1,2,3,5. So I setup a loop in just a normal C program to do this:
for(int m=1; m<=a;m++)
{
i = (pow(c, m)-(pow(v, m)))/b;
printf("%d\n",(int)round(i));
}
This for loop gives me the desired output I am looking for. But, when I put it into a child process of the fork method, the output changes. I.e. if the user inputs 5, the output will be 1,0,2,2,5. Why is this? and is there a way to fix it? Here is my code:
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <math.h>
int var_glb; /* A global variable*/
int main(void)
{
pid_t childPID;
double a;
double c = 1.6180339;
double v = -0.6190339;
double b = 2.236067977;
int i;
childPID = fork();
if(childPID >= 0) // fork was successful
{
if(childPID == 0) // child process
{
printf("\nEnter the first value:");
scanf("%lf", &a);
for(int m=1; m<=a;m++)
{
i = (pow(c, m)-(pow(v, m)))/b;
printf("%d\n",(int)round(i));
}
}
else //Parent process
{
wait(NULL);
printf("\nThis is the parent process running");
return 0;
}
}
else // fork failed
{
printf("\n Fork failed, quitting!!!!!!\n");
return 1;
}
return 0;
}
I would start by fixing your brackets: i = (pow(c, m)-pow(v, m))/b; Also You cannot expect i to be int... i should be float or double
Your problem is not related to forking. The program produces exactly the same result if all the forking is commented out, and everything runs in the parent process. Apparently the algorithm is incorrect in some way.
So I found that the problem was that i declared the variable i as an int instead of a double, as I had did in another application, thanks for you help though, I will definitely use all of your suggestions to strengthen my code.
I want to count the number of processes that are created with a for 1,10 and where fork() si executed. The program is executed in linux. I really don't get how to use wait or WEXITSTATUS and I've spent hours on forums and still don't get it. Can someone help me, please?
Thanks,
Dragos
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int nr = 1;
int main()
{
int pid;
int i;
int stare;
for(i = 1; i<=10 ; i++)
{
pid = fork();
if( pid !=0 )
{
//parent
wait(&stare);
nr = nr + stare;
}
else
{
//child
nr++;
stare = WEXITSTATUS(nr);
exit(nr);
}
}
printf("\nNr: %d\n", nr);
}
The macros like WEXITSTATUS are used in the parent process to get the exit status after a wait call.
In the child process, it's enough to just return nr (or call exit with it as argument).
In the parent you use WEXITSTATUS like this:
if (wait(&stare) > 0)
{
if (WIFEXITED(stare))
nr += WEXITSTATUS(stare);
}
We must use the WIFEXITED check because otherwise the exit status is not valid.