I have a school project which requires me to simulate first come first serve using these variables:
Users Input:
Number of Process: 3
Process 1 Arrives at 0 time and requires 5 'resources'
3
1,5,0
2,5,4
3,1,8
However, i can't seem to get past the first 5 'resources'. I'm trying to figure out how to increase PID and repeat but keep time increasing for all these resources. I've created this same program but it only allows for this specific input and I'm trying to make it more versatile so i can choose any number of processes and resources(unit) needed.
#include <stdio.h>
main() {
int n;
printf("Enter the Amount of processes: ");
scanf("%d",&n);
//Variables
int process[n], unit[n], at[n];
int i,time,PID = 1;
int awt, atat,sum,counter;
int x = n;
//Takes and stores the users input into process unit and at
for(i=0;i<n;i++)
{
scanf("%d,%d,%d", &process[i], &unit[i], &at[i]);
}
sum = sum_array(unit,n);
printf("%d\n", sum);
printf("FCFS\n");
printf("Time PID");
for(counter = 0; counter < x; counter++, PID++){
FCFS(time,n,unit,PID);
}
}
int sum_array(int at[], int num_elements){
int x, sum = 0;
for(x=0; x<num_elements;x++){
sum = sum + at[x];
}
return(sum);
}
int FCFS(int time,int n,int unit[], int PID){
for(time = 0, n = 0 ; unit[n] >0 ;time++, unit[n]--){
printf("\n%d ", time);
printf("%d", PID);
}
return;
}
Sample Output:
FCFS
TIME PID
0 1
1 1
2 1
3 1
4 1
5 2
6 2
7 2
8 2
9 2
10 3
Your problems are mostly related to the FCFS function and the loop where you call it.
Try the following:
Initialize time = 0 in the main function
Pass counter instead of n to FCFS in the loop
Return the updated time from FCFS
Don't reset the time and n parameter inside FCFS
Call to FCFS inside for loop:
time = FCFS(time, counter, unit, PID);
Updated FCFS code:
int FCFS(int time,int n,int unit[], int PID)
{
for( ; unit[n] >0 ;time++, unit[n]--)
{
printf("\n%d ", time);
printf("%d", PID);
}
return time;
}
Other than that, there are a number of issues with your code, but it wouldn't really fit into this Q/A to mention them all, so I stick with the necessary things to get your code running for valid example input.
Since this is a homework question, I would encourage you to solve it on your own. Since you have put in some effort on solving this, I am posting the answer below as a spoiler (Note indentation does not work in spoilers). However before seeing the answer here are few suggestions to fix your program:
As mentioned above, passing n does absolutely nothing. Please use a different variable inside the FCFS function.
No need to increment and pass the PID. Since you are putting it in an array, try to get the value from the array.
Instead of n pass counter to the function so that you can index the two arrays.
The for loop inside FCFS makes no sense. It should be for(i=0; i<unit[counter]; i++). time can just be incremented inside the loop.
time needs to be returned to increment properly
And my code:
int time = 0;
int cur_index = 0;
while (cur_index < n) {
int pid = -1;
if (at[cur_index] <= time) {
pid = process[cur_index];
} else {
printf("%d %d\n", time, pid);
time++;
continue;
}
if (pid != -1) {
int r = 0;
for (r = 0; r < unit[cur_index]; r++) {
printf("%d %d\n", time, pid);
time++;
}
}
}
Related
The C script is supposed to take x amount of CPU bound forks and x amount of IO bound forks, so then lets say 10 total processes if you there's 5 of each. If I fork 10 times, then 5 of those should go to working on the CPU bound "fake work" and 5 of those should go to the IO bound "fake work". Waitstats is a custom function that serves the purpose of wait while also displaying rtime and wtime.
My problem is that I've tried multiple configurations and I'm not sure how to get the Process Number printf to correctly print, only 10 times, if there's only 10 forks? I also feel as if I'm not doing my fake work correctly for the CPU/IO bound work.
Any help here would be appreciated!
`
int main(int argc, char* argv[])
{
int cpuNum = atoi(argv[2]);
int ioNum = atoi(argv[4]);
int const MAX_PROC = cpuNum + ioNum;
printf("\nMax Proc %d", MAX_PROC);
int totRunTime = 0;
int totWaitTime = 0;
uint rTime = 0;
uint wTime = 0;
int pid = 0;
//Create Max_Proc Forks
for(int n=0; n < MAX_PROC; n++)
{
pid = fork();
//If Child, Exceute Command
if(pid == 0)
{
break;
}
}
if (cpuNum > 0) {
//CPU Busy Work
for (volatile int i = 0; i < 1000000000; i++){}
cpuNum--;
}
else if (ioNum > 0) {
//IO Busy Work
sleep(200);
ioNum--;
}
for(int p=0; p < MAX_PROC; p++)
{
printf("\n Process %d finished", p);
if(waitStats(0, &rTime, &wTime) >= 0)
{
totRunTime += rTime;
totWaitTime += wTime;
}
}
printf("\nAverage rtime %d, wtime %d", rTime, wTime);
exit(0);
}
`
I've tried multiple configurations, but can't seem to get the printf to print the correct process/fork number. For instance forking 10 times would mean I would need to printf every time one of those forks finished their task (10 total times).
The code shown doesn't print pids, so I'm assuming you mean "process number" as in 1st child, 2nd child etc.
Every one of your processes is running this:
for(int p=0; p < MAX_PROC; p++)
{
printf("\n Process %d finished", p);
...
So it looks like each process will print the numbers 0 .. MAX_PROC-1 (with no indication of which pid is printing)
Have you tried putting the waitStats for loop inside of your "Create Max_Proc Forks" for loop? So then basically everything should be inside of the first loop, probably giving you a good way to keep track of the process number?
I am working with a large project and I am trying to create a test that does the following thing: first, create 5 threads. Each one of this threads will create 4 threads, which in turn each one creates 3 other threads. All this happens until 0 threads.
I have _ThreadInit() function used to create a thread:
status = _ThreadInit(mainThreadName, ThreadPriorityDefault, &pThread, FALSE);
where the 3rd parameter is the output(the thread created).
What am I trying to do is start from a number of threads that have to be created n = 5, the following way:
for(int i = 0; i < n; i++){
// here call the _ThreadInit method which creates a thread
}
I get stuck here. Please, someone help me understand how it should be done. Thanks^^
Building on Eugene Sh.'s comment, you could create a function that takes a parameter, which is the number of threads to create, that calls itself recursively.
Example using standard C threads:
#include <stdbool.h>
#include <stdio.h>
#include <threads.h>
int MyCoolThread(void *arg) {
int num = *((int*)arg); // cast void* to int* and dereference
printf("got %d\n", num);
if(num > 0) { // should we start any threads at all?
thrd_t pool[num];
int next_num = num - 1; // how many threads the started threads should start
for(int t = 0; t < num; ++t) { // loop and create threads
// Below, MyCoolThread creates a thread that executes MyCoolThread:
if(thrd_create(&pool[t], MyCoolThread, &next_num) != thrd_success) {
// We failed to create a thread, set `num` to the number of
// threads we actually created and break out.
num = t;
break;
}
}
int result;
for(int t = 0; t < num; ++t) { // join all the started threads
thrd_join(pool[t], &result);
}
}
return 0;
}
int main() {
int num = 5;
MyCoolThread(&num); // fire it up
}
Statistics from running:
1 thread got 5
5 threads got 4
20 threads got 3
60 threads got 2
120 threads got 1
120 threads got 0
Write a C program that sets an environment variable called done to 0.
The program will then ask the user to enter 5 numbers in a loop and store the numbers in an array of 5 int elements.
The program will then creates a clone process (using fork()).
The clone should run a function called sum() that calculates the total sum of all the numbers in the array.
After that the clone will set the done environment variable to 1. It will also create a second environment variable called result and will set it to the return value of the sum()function.
The parent process wait on done variable until it is set to 1.
If it is 1, the parent will print to the screen : The sum of elements is: result.
Note that result is the content of the environment variable called result.
Please note that you need to choose a suitable signature for your sum()function,
meaning that it is up to you to decide about the type and the number of arguments as well as the type of the return value.
I am not sure why my program is not working.
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int sum(int a[], int size) {
int index, result = 0;
for (index = 0; index < size; index++) {
result+=a[index];
return result;
}
}
int main() {
int i, array[5], result;
long pid;
char string[20];
for (i = 0; i < 5; i++) {
scanf("%d", &array[i]);
if (i == 4) {
}
}
setenv("done", "0", 1);
pid = fork();
if (pid == 0) {
result = sum(array,5);
sprintf(string, "%d", result);
setenv("result", string, 1);
setenv("done","1",1);
}
else {
while (strcmp(getenv("done"), "0") == 0) {
}
result = atoi(getenv("result"));
printf("The sum of elements is %d\n", result);
}
return 0;
}
This my not be the answer you desire, but 2 way communication via environment variable is near impossible because as pointed out in the comment a child process could not affect its parent process environment.
I would suggest you look at inter process communication :
Shared memory
Pipe
Socket
RPC
I'm trying to create a hash table. Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define N 19
#define c1 3
#define c2 5
#define m 3000
int efort;
int h_table[N];
int h(int k, int i)
{
return (k + i*c1 + i*i*c2) % N;
}
void init()
{
for (int i = 0; i < N; i++)
h_table[i] = -1;
}
void insert(int k)
{
int position, i;
i = 0;
do
{
position = h(k, i);
printf("\n Position %d \n", position);
if (h_table[position] == -1)
{
h_table[position] = k;
printf("Inserted :elem %d at %d \n", h_table[position], position);
break;
}
else
{
i += 1;
}
} while (i != N);
}
void print(int n)
{
printf("\nTable content: \n");
for (int i = 0; i < n; i++)
{
printf("%d ", h_table[i]);
}
}
void test()
{
int a[100];
int b[100];
init();
memset(b, -1, 100);
srand(time(NULL));
for (int i = 0; i < N; i++)
{
a[i] = rand() % (3000 + 1 - 2000) + 2000;
}
for (int i = 0; i < N ; i++)
{
insert(a[i]);
}
print(N);
}
int main()
{
test();
return 0;
}
Hash ("h") function and "insert" function are took from "Introduction to algorithms" book (Cormen).I don't know what is happening with the h function or insert function. Sometimes it fills completely my array, but sometimes it doesn't. That means it doesn't work good. What am I doing wrong?
In short, you are producing repeating values for position often enough to prevent h_table[] from being populated after only N attempts...
The pseudo-random number generator is not guaranteed to produce a set of unique numbers, nor is your h(...) function guaranteed to produce a mutually exclusive set of position values. It is likely that you are generating the same position enough times that you run out of loops before all 19 positions have been generated. The question how many times must h(...) be called on average before you are likely to get the value of an unused position? should be answered. This may help to direct you to the problem.
As an experiment, I increased the looping indexes from N to 100 in all but the h(...) function (so as not to overrun h_table[] ). And as expected the first 5 positions filled immediately. The next one filled after 3 more tries. The next one 10 tries later, and so on, until by the end of 100 tries, there were still some unwritten positions.
On the next run, all table positions were filled.
2 possible solutions:
1) Modify hash to improve probability of unique values.
2) Increase iterations to populate h_table
A good_hash_function() % N may repeat itself in N re-hashes. A good hash looks nearly random in its output even though it is deterministic. So in N tries it might not loop through all the array elements.
After failing to find a free array element after a number of tries, say N/3 tries, recommend a different approach. Just look for the next free element.
Im trying to create a multithreaded application in C for Linux with pthreads library that makes an approximation of pi using infinite series with N+1 terms.Variable N and T are passed from the command line. I am using the Nilakantha approximation formula for pi. N is the upper limit of the number sequence to sum and T would be the # of child threads that calculate that sum. For example if I run command "./pie 100 4". The parent thread will create 4 child threads indexed 0 to 3. I have a global variable called vsum that is a double array allocated dynamically using malloc to hold values. So with 4 threads and 100 as the upper bound. My progam should compute:
Thread 0 computes the partial sum for i going from 0 to 24 stored to an element vsum[0]
Thread 1 computes the partial sum for i going from 25 to 49 stored to an element vsum[1]
Thread 2 computes the partial sum for i going from 50 to 74 stored to an element vsum[2]
Thread 3 computes the partial sum for i going from 75 to 99 stored to an element vsum[3]
After each thread makes calculations. The main thread will compute the sum by adding together all numbers from vsum[0] to vsum[T-1].
Im just starting to learn about threads and processes. Any help or advice would be appreciated. Thank you.
Code I wrote so far:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
double *vsum;
int N, T;
void *PI(void *sum) //takes param sum and gets close to pi
{
int upper = (int)sum;
double pi = 0;
int k = 1;
for (int i = (N/T)*upper; i <= (N/T)*(upper+1)-1; i++)
{
pi += k*4/((2*i)*(2*i+1)*(2*i+2));
if(i = (N/T)*(upper+1)-1)
{
vsum[upper] = pi;
}
k++;
}
pthread_exit(0);
}
int main(int argc, char*argv[])
{
T = atoi(argv[2]);
N = atoi(argv[1]);
if (N<T)
{
fprintf(stderr, "Upper bound(N) < # of threads(T)\n");
return -1;
}
int pie = 0;
pthread_t tid[T]; //thread identifier
pthread_attr_t attr; //thread attributes
vsum = (double *)malloc(sizeof(double));//creates dyn arr
//Initialize vsum to [0,0...0]
for (int i = 0; i < T; i++){
{
vsum[i] = 0;
}
if(argc!=2) //command line does not give proper # of values
{
fprintf(stderr, "usage: commandline error <integer values>\n");
return -1;
}
if (atoi(argv[1]) <0) //if its is negative/sum error
{
fprintf(stderr, "%d must be >=0\n", atoi(argv[1]));
return -1;
}
//CREATE A LOOP THAT MAKES PARAM N #OF THREADS
pthread_attr_init(&attr);
for(int j =0; j < T;j++)
{
int from = (N/T)*j;
int to = (N/T)*(j+1)-1;
//CREATE ARRAY VSUM TO HOLD VALUES FOR PI APPROX.
pthread_create(&tid[j],&attr,PI,(void *)j);
printf("Thread %d computes the partial sum for i going from %d to %d stored to an element vsum[%d]\n", j, from, to, j);
}
//WAITS FOR THREADS TO FINISH
for(int j =0; j <T; i++)
{
pthread_join(tid[j], NULL);
}
//LOOP TO ADD ALL THE vsum array values to get pi approximation
for(int i = 0; i < T; i++)
{
pie += vsum[i];
}
pie = pie +3;
printf("pi computed with %d terms in %d threads is %d\n",N,T,pie);
vsum = realloc(vsum, 0);
pthread_exit(NULL);
return 0;
}
Here is the error I dont see that I get on my program: What am I missing here?
^
pie.c:102:1: error: expected declaration or statement at end of input
}
When I try to run my program I get the following:
./pie.c: line 6: double: command not found
./pie.c: line 7: int: command not found
./pie.c: line 8: int: command not found
./pie.c: line 10: syntax error near unexpected token `('
./pie.c: line 10: `void *PI(void *sum) //takes param sum and gets close to pi'
I haven't looked at logic of your code, but I see following programming errors.
Change
pthread_create(&tid[j],&attr,PI,j);
to
pthread_create(&tid[j],&attr,PI,(void *)j);
pthread_create() takes 4th param as void * which is passed to the thread function.
Also fix your thread function PI to use passed parameter as int like
void *PI(void *sum) //takes param sum and gets close to pi
{
int upper = (int)sum; //don't use `atoi` as passed param is int.
...
//your existing code
}
The 3rd error is for line
realloc(vsum, 0);
By passing 0 to re-allocate, you are effectively just freeing vsum, so you can just use free(vsum). If you indeed want to reallocate you should take the new allocated memory returned by the function something like vsum = realloc(vsum, 0);
The Syntax of pthread is
pthread_create(threadId, threadAttribute, callingMethodName, parameters of calling method);
Ex:
void printLetter( void *p)
{
int i=0;
char c=(char *)p;
while (i<10000)
{
printf("%c",c);
}
}
int main()
{
pthread_t thread_id;
char c='x';
pthread_create (&thread_id, NULL, &printLetter, &c);
pthread_join (thread_id, NULL);
return 0;
}
}