CS441 - Homework #3
/********************************
Name: Thomas Heffron (tehqnf@umkc.edu)
Section: CS431 NET
Program: Program #3 - Part #3
Due Date: Oct. 15, 2002
Desc: Write a program that creates multiple
threads (using __clone) and
terminates after a period of time.
Inputs: Cmd arguments given for number of
threads to create and duration of
main process.
Outputs: Timestamp showing beginning of main thread.
Timestamp showing creation of additional threads.
Work function will show each major work loop.
Timestamp showing termination of main thread.
********************************/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <sys/time.h>
#include <sys/types.h>
extern int errno;
/* Function declarations */
void *work(void *arg);
static void sig_alarm(int signo);
int flag = 1; /* flag used to indicate thread termination */
int main(int argc, char *argv[])
{
/* Variable declarations */
int num_threads, proc_duration, thread_no;
time_t now;
pid_t pid;
void *csp, *tcsp;
if (argc == 3) { /* Check for correct number of args */
num_threads = atoi(argv[1]); /* translate cmd args */
proc_duration = atoi(argv[2]);
time(&now);
printf("Thread creation started at %s", ctime(&now));
if (signal(SIGALRM, sig_alarm) == SIG_ERR) { /* define signal catch */
printf("The signal function returned an error\n");
exit(1);
}
printf("Setting alarm to end process in %d seconds.\n\n",
proc_duration);
alarm(proc_duration); /* set alarm */
thread_no = 1; /* initialize thread count to one and */
while (thread_no <= num_threads) { /* create requested threads */
csp = (int *)malloc(8192*8);
if (csp)
tcsp = csp + 8192 * 8;
else
exit(errno);
if (( pid = clone( (void *)&work, tcsp,
CLONE_VM,
(void *)&thread_no)) < 0) {
printf("Couldn't create new thread!\n");
exit(1);
} else { /* we are in main thread */
time(&now);
printf("Created thread no. %d for work() at %s",
thread_no, ctime(&now));
sleep(1); /* delay to allow thread to spawn */
thread_no++; /* or else increment may occur first */
}
}
while (1); /* main thread must cycle - sig_alarm will call exit() */
} else {
printf("Usage: %s num_threads proc_duration\n", argv[0]);
exit(1);
}
}
static void sig_alarm(int signo)
{
time_t now;
alarm(0);
printf("*** Alarm to end process ***\n");
time(&now);
printf("Process ending at %s\n", ctime(&now));
flag = 0; /* raise flag to signal threads to terminate */
exit(0);
}
void *work(void *arg)
{
double y;
double x = 3.0;
double e = 2.0;
int i, j, childnum;
childnum = *(int *) arg;
while (1) {
for (i = 0; i < 5; i++) {
for (j = 0; j < 400000; j++) {
y = pow(x, e);
}
if (flag == 0) exit(0); /* this proc terms if main exits */
printf("Loop %d of thread %d work cycle\n", i, childnum);
sleep(1);
}
if (flag == 0) exit(0); /* this proc terms if main exits */
printf("End of thread %d work. Resetting...\n", childnum);
}
}