P09 lab code added

This commit is contained in:
Andreas Gieriet 2020-04-26 15:02:50 +02:00
parent 94945069e3
commit f4c374887c
45 changed files with 2116 additions and 0 deletions

View File

@ -0,0 +1,178 @@
/******************************************************************************
* File: Daemonizer.c
* Original Autor: M. Thaler (Modul BSY)
* Aufgabe: Einen Daemon-Prozess erzeugen
******************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
//*****************************************************************************
// Macro to write out all the PIDs...
#define OutPutPIDs() /*printf("\nPID %d, PPID %d, GRP-ID %d\n", \
getpid(), getppid(), getpgrp())*/
//*****************************************************************************
// Function: Locks file with file descriptor fd
// Returns: 0 on success, -1 of file is already locked
// Exits: on fatal errors
//*****************************************************************************
int lock(int fd) {
int retval, len;
struct flock lock; // data structure for file lock
char buffer[16];
// prepare lockfile
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
retval = fcntl(fd, F_SETLK, &lock); // set file lock
if (retval < 0) {
if ((errno == EACCES) || (errno == EAGAIN)) {
return(-1); // Daemon already runs
}
else {
perror("fatal error when locking file");
exit(-1);
}
}
// empty the lockfile
retval = ftruncate(fd, 0);
if (retval < 0) {
perror("fatal error when emptying lockfile");
exit(-1);
}
// write process ID to lockfile
sprintf(buffer, "%d\n", getpid());
len = strlen(buffer);
retval = write(fd, buffer, len) < len;
if (retval < 0) {
perror("fatal error when writing pid to lockfile");
exit(-1);
}
// set lockfile to close on exec
retval = fcntl(fd, F_GETFD, 0);
if (retval < 0) {
perror("fatal error when reading lockfile flags");
exit(-1);
}
retval = retval | FD_CLOEXEC;
retval = fcntl(fd, F_SETFD, retval);
if (retval < 0) {
perror("fatal error when setting lockfile flags");
exit(-1);
}
return(0);
}
//*****************************************************************************
// Function: Makes a deamon process and runs a daemon function
// Parameter: Daemon function
// data pointer to data to be passed to Daemonfunction
// LogFile, path of logfile, if NULL, no logfile is created
// LivDir, path, where daemon will live
// Returns: should not return
// Exits: if daemon is already runnung or on fatal errors
//*****************************************************************************
int Daemonizer(void Daemon(void *), void *data,
const char *LockFile, const char *LogFile, const char *LivDir) {
pid_t PID;
int fd, dummyfd, retval;
// create a prozess and terminate parents -> parent is init
OutPutPIDs();
PID = fork();
if (PID < 0) {
perror("could not fork()");
exit(-1);
}
else if (PID > 0) {
exit(0); // I have done my work an can exit
}
// ----------------------------------------------------------------------
// now I am a process detached from the parent
// an make the process -> a daemon process
signal(SIGINT, SIG_IGN); // ignore CTRL-C
signal(SIGQUIT, SIG_IGN); // ignore quit
signal(SIGHUP, SIG_IGN); // ignore hangup of terminal
OutPutPIDs();
setsid(); // make process session leader
// and processgroup leader
// no control terminal with pocess
OutPutPIDs();
chdir(LivDir); // change to secure directory
umask(0); // allow all access rights for files
// set up lockfile, if required
if (LockFile != NULL) {
fd = open(LockFile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
S_IRGRP | S_IROTH);
if (fd < 0) {
perror("fatal error when opening lockfile");
exit(-1);
}
retval = lock(fd);
if (retval < 0) {
printf("\n*** daemon is already running ***\n");
exit(0);
}
}
// last message from daemon
printf("\n*** daemon starts with process id: %d ***\n",getpid());
// close "communication" to outer world and set up logging, if required
close(1); // close stdout
close(2); // close stderr
if (LogFile != NULL) { // open log file on stdout
enum {UserWrite=0644};
dummyfd = open(LogFile, O_CREAT | O_APPEND | O_WRONLY,UserWrite);
if (dummyfd < 0) {
perror("could not open log file");
exit(-1);
}
dup(1); // connect stderr to logfile
}
close(0); // now close stdin
// now start the daemon funktion
Daemon(data);
// should not come here
return(0);
}
//*****************************************************************************

View File

@ -0,0 +1,15 @@
/*********************************************************************
* File: Daemonizer.h
* Original Autor: M. Thaler (Modul BSY)
* Aufgabe: einen Daemon-Prozess erzeugen
*********************************************************************/
#ifndef DAEMONIZER_H
#define DAEMONIZER_H
int Daemonizer(void Daemon(void *), void *data,
const char *LockFile, const char *LogFile, const char *LivDir);
#endif
//------------------------------------------------------------------------

View File

@ -0,0 +1,188 @@
//*****************************************************************************
// ipCom.c IP Socket Functions
// Original Author: M. Thaler, M. Pellaton (Modul BSY)
//*****************************************************************************
//*****************************************************************************
// system includes
//*****************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <net/if.h>
//*****************************************************************************
// local definitions
//*****************************************************************************
#include "IPsockCom.h"
//*****************************************************************************
// Function: send data buffer to host "host" with port "port"
// Parameter: hostname or IP address in dot format
// port number
// buffer
// size of buffer
// Returns: number of characters read on success, -1 if connection failed
// buffer: time data
//
//*****************************************************************************
int getTimeFromServer(char *host, int port, char *buffer, int bufferLen) {
int sfd, sysRet, timeOut, retval;
char stringPort[8];
struct addrinfo hints, *aiList, *aiPtr = NULL;
if (strcmp(host, "") == 0) {
printf("Need hostname or IP address\n");
return(-1);
}
sprintf(stringPort, "%d", port);
memset(&hints, '\0', sizeof(hints));
//hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
sysRet = getaddrinfo(host, stringPort, &hints, &aiList);
if (sysRet != 0) {
printf("error getting network address for %s (%s)\n",
host, gai_strerror(sysRet));
exit(-1);
}
aiPtr = aiList; // search through list
while (aiPtr != 0) {
sfd = socket(aiPtr->ai_family, aiPtr->ai_socktype, aiPtr->ai_protocol);
if (sfd >= 0) {
timeOut = 100;
sysRet = 1;
while ((timeOut != 0) && (sysRet != 0)) {
sysRet = connect(sfd, aiPtr->ai_addr, aiPtr->ai_addrlen);
usleep(1000);
timeOut--;
}
if (sysRet == 0)
break; // connect successful
else
close(sfd);
}
aiPtr = aiPtr->ai_next;
}
freeaddrinfo(aiList);
if (aiPtr == NULL) {
printf("could not connect to %s\n", host);
retval = -1;
}
else
retval = 0;
if (retval == 0) {
if (write(sfd, buffer, bufferLen) < 0) {
printf("error sending request to timer serveer\n");
retval = -1;
}
else
retval = read(sfd, buffer, COM_BUF_SIZE);
}
close(sfd);
return(retval);
}
//*****************************************************************************
// Function: starts "time" socket server
// Parameter: port number to listen to
// Returns: socket file descriptor if ok, -1 if error
// Exits:
//*****************************************************************************
int StartTimeServer(int portNumber) {
int sfd, sysRet, j;
char stringPort[8];
struct addrinfo hints, *aiList, *aiPtr = NULL;
sprintf(stringPort, "%d", portNumber); // portnumber to string
memset(&hints, '\0', sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_PASSIVE;
sysRet = getaddrinfo(NULL, stringPort, &hints, &aiList);
if (sysRet != 0) {
printf("error getting network address (%s)\n", gai_strerror(sysRet));
exit(-1);
}
aiPtr = aiList; // search through list
while (aiPtr != 0) {
sfd = socket(aiPtr->ai_family, aiPtr->ai_socktype, aiPtr->ai_protocol);
if (sfd >= 0) {
j = 1;
sysRet = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &j, sizeof(j));
if (sysRet < 0)
perror("cannot set socket options");
if (bind(sfd, aiPtr->ai_addr, aiPtr->ai_addrlen) < 0) {
perror("bind failed ");
close(sfd);
exit(-1);
}
if (listen(sfd, 5) < 0) {
close(sfd);
perror("listen failed ");
exit(-1);
}
else
break;
}
aiPtr = aiPtr->ai_next;
}
freeaddrinfo(aiList);
if (aiPtr == NULL) {
printf("could not set up a socket server\n");
exit(-1);
}
return(sfd);
}
//*****************************************************************************
// Function: Reads data from client
// Parameter: socket file descriptor
// buffer to place data
// Returns: current socket descriptor on success, < 0 on failure
// Exits: none
//*****************************************************************************
int WaitForClient(int sfd, char *buffer) {
int cfd, retval, addrlen;
struct sockaddr_in addr;
addrlen = sizeof(struct sockaddr_in);
cfd = accept(sfd,(struct sockaddr *)&addr,(socklen_t *)&addrlen);
if (cfd >= 0) {
retval = read(cfd, buffer, COM_BUF_SIZE);
retval = cfd;
}
else
retval = cfd;
return(retval);
}
//*****************************************************************************

View File

@ -0,0 +1,20 @@
//*****************************************************************************
// ipCom.c IP Socket Functions
// Original Autor: M. Thaler, M. Pellaton (Modul BSY)
//*****************************************************************************
#ifndef IP_COM_SOCKETS
#define IP_COM_SOCKETS
#define COM_BUF_SIZE 512
#define PIDperror()\
fprintf(stderr,"fatal error, daemon with PID %d: ",getpid());
int getTimeFromServer(char *host, int port, char *buffer, int bufferLen);
int StartTimeServer(int PortNumber);
int WaitForClient(int sfd, char *buffer);
#endif
//***************************************************************************

View File

@ -0,0 +1,44 @@
/*********************************************************************
* File: MrTimeDaemon.c
* Original Autor: M. Thaler (Modul BSY)
* Aufgabe: einen Daemon-Prozess erzeugen
*********************************************************************/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "Daemonizer.h"
#include "TimeDaemon.h"
#define STRING_LENGTH 128
//--------------------------------------------------------------------
int main(void) {
pid_t pid;
int status;
const char *lockfilePath = "/tmp/timeDaemon.lock";
//const char *lockfilePath = NULL;
const char *logfilePath = "/tmp/timeDaemon.log";
const char *livingPath = "/tmp";
const char *myName = "I am Mr. Time Daemon on \n";
if ((pid = fork()) == 0)
Daemonizer(TimeDaemon, (void *)myName,
lockfilePath, logfilePath, livingPath);
else {
assert(pid > 0);
wait(&status); // wait for Daemonizer to exit
// after having forked the "Daemon"
if (WEXITSTATUS(status) != 0)
printf("*** Daemonizer failed ***\n");
}
}
//--------------------------------------------------------------------

View File

@ -0,0 +1,21 @@
/*********************************************************************
* File: PlapperMaul.c
* Original Autor: M. Thaler (Modul BSY)
* Aufgabe: plappern
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//--------------------------------------------------------------------
int main(void) {
while (1) {
printf("Hallo, ich bins.... Pidi %d\n", getpid());
usleep(500000);
}
}
//--------------------------------------------------------------------

View File

@ -0,0 +1,75 @@
/******************************************************************************
* File: TimeDaemon.c
* Original Autor: M. Thaler (Modul BSY)
* Aufgabe: the daemon code
******************************************************************************/
//*****************************************************************************
// system includes
//*****************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/un.h>
#include <netdb.h>
#include <time.h>
//*****************************************************************************
// local includes
//*****************************************************************************
#include "TimeDaemon.h"
#include "TimeDaemonDefs.h"
#include "IPsockCom.h"
//*****************************************************************************
// Function: TimeDeamon
// Parameter: data: expects here pointer to string
//*****************************************************************************
void TimeDaemon(void *data) {
TimeData tData;
char buffer[COM_BUF_SIZE];
struct tm MyTime;
time_t ActualTime;
int sfd, cfd;
printf("%s\n", (char *)data);
// start server
sfd = StartTimeServer(TIME_PORT);
if (sfd < 0) {
perror("could not start socket server");
exit(-1);
}
while (1) {
cfd = WaitForClient(sfd, buffer);
if ((strcmp(buffer, REQUEST_STRING) == 0) && (cfd >= 0)) {
time(&ActualTime);
MyTime = *localtime(&ActualTime);
tData.hours = MyTime.tm_hour;
tData.minutes = MyTime.tm_min;
tData.seconds = MyTime.tm_sec;
tData.day = MyTime.tm_mday;
tData.month = MyTime.tm_mon + 1;
tData.year = MyTime.tm_year + 1900;
gethostname(tData.servername, HOST_NAM_LEN);
write(cfd, (char *)(&tData), sizeof(tData));
}
}
// if we should somehow come here (how ?)
close(sfd);
exit(0);
}
//*****************************************************************************

View File

@ -0,0 +1,14 @@
/******************************************************************************
* File: TimeDaemon.h
* Original Autor: M. Thaler (Modul BSY)
* Aufgabe: function prototype of time daemon
******************************************************************************/
#ifndef TIME_DAEMON
#define TIME_DAEMON
void TimeDaemon(void *);
#endif
//*****************************************************************************

View File

@ -0,0 +1,30 @@
/******************************************************************************
* File: TimeDaemonDefs.h
* Original Autor: M. Thaler (Modul BSY)
* Aufgabe: Data Definitions for TimeDaemon
******************************************************************************/
#ifndef TIME_DAEMON_DEFS
#define TIME_DAEMON_DEFS
#define HOST_NAM_LEN 32
#define TIME_PORT 65534
#define REQUEST_STRING "requestTimeFromServer"
// data structure receiving from time daemon
typedef struct {
int hours;
int minutes;
int seconds;
int day;
int month;
int year;
char servername[HOST_NAM_LEN];
} TimeData, *TimeDataPtr;
#endif
//*****************************************************************************

View File

@ -0,0 +1,66 @@
/******************************************************************************
* File: WhatsTheTimeMr.c
* Original Autor: M. Thaler (Modul BSY)
* Aufgabe: Ask MrTimeDaemon for the time
******************************************************************************/
//*****************************************************************************
// system includes
//*****************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/un.h>
#include <netdb.h>
#include <arpa/inet.h> // required by inet_aton
//*****************************************************************************
// local includes
//*****************************************************************************
#include "TimeDaemon.h"
#include "TimeDaemonDefs.h"
#include "IPsockCom.h"
//*****************************************************************************
// Function: main()
// Parameter: hostname or IP address in dot format
//*****************************************************************************
int main(int argc, char *argv[]) {
char buffer[COM_BUF_SIZE];
char hostname[64];
TimeDataPtr tDataPtr;
int j;
if (argc < 2) {
printf("*** no hostname or IP-address -> using localhost ***\n");
strcpy(hostname, "localhost");
} else {
strcpy(hostname, argv[1]);
}
strcpy(buffer,REQUEST_STRING);
j = getTimeFromServer(hostname, TIME_PORT, buffer, sizeof(buffer));
if (j < 0)
printf("no response from %s\n", argv[1]);
else {
tDataPtr = (TimeDataPtr)(buffer);
printf("\nIt's ");
printf("%02d:%02d:%02d",
tDataPtr->hours, tDataPtr->minutes,tDataPtr->seconds);
printf(" the %d.%d.%d on \"%s\"\n\n",
tDataPtr->day, tDataPtr->month,
tDataPtr->year, tDataPtr->servername);
}
exit(0);
}
//*****************************************************************************

View File

@ -0,0 +1,35 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc
CMPFLAGS= -Wall -g -std=gnu99
EXENAMES= MrTimeDaemon.e
EXENAMEC= WhatsTheTimeMr.e
EXENAMEP= PlapperMaul.e
LIBNAME=
compile: $(EXENAMES) $(EXENAMEC) $(EXENAMEP)
$(EXENAMES): MrTimeDaemon.o IPsockCom.o Daemonizer.o TimeDaemon.o
$(CMP) $(CMPFLAGS) MrTimeDaemon.o IPsockCom.o Daemonizer.o TimeDaemon.o $(LIBNAME) -o $(EXENAMES)
$(EXENAMEC): WhatsTheTimeMr.o IPsockCom.o
$(CMP) $(CMPFLAGS) WhatsTheTimeMr.o IPsockCom.o $(LIBNAME) -o $(EXENAMEC)
$(EXENAMEP): PlapperMaul.o
$(CMP) $(CMPFLAGS) PlapperMaul.o $(LIBNAME) -o $(EXENAMEP)
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f $(EXENAMEC) $(EXENAMES) $(EXENAMEP)
rm -f *.o
all:
@make clean
@make

View File

@ -0,0 +1,53 @@
//***************************************************************************
// File: ProcA1.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
pid_t pid;
int status;
int i;
i = 5;
printf("\n\ni vor fork: %d\n\n", i);
pid = fork();
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0:
i++;
printf("\n... ich bin das Kind %d mit i=%d, ", getpid(),i);
printf("meine Eltern sind %d \n", getppid());
break;
default:
i--;
printf("\n... wir sind die Eltern %d mit i=%d ", getpid(), i);
printf("und Kind %d,\n unsere Eltern sind %d\n", pid, getppid());
wait(&status);
break;
}
printf("\n. . . . . und wer bin ich ?\n\n");
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,26 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc
CMPFLAGS= -Wall
LDFLAGS=
EXENAM1= ProcA1.e
FNAM1= ProcA1
LIBNAME=
$(EXENAM1): $(FNAM1).o
$(CMP) $(FNAM1).o $(LIBNAME) $(LDFLAGS) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f *.o $(EXENAM1)
all:
@make clean
@make

View File

@ -0,0 +1,38 @@
//***************************************************************************
// File: ChildProcA3.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//***************************************************************************
// Function: main(), parameter: arg[0]: Programmname, arg[1]: i
//***************************************************************************
int main(int argc, char *argv[]) {
int i;
if (argv[1] == NULL) {
printf("argument missing\n");
exit(-1);
}
else
i = atoi(argv[1]); // convert string argv[1] to integer i
// argv[1] is a number passed to child
printf("\n... ich bin das Kind %d mit i=%d, ", getpid(),i);
printf("meine Eltern sind %d \n", getppid());
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,54 @@
//***************************************************************************
// File: ProcA3.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
pid_t pid;
int status;
int i, retval;
char str[8];
i = 5;
printf("\n\ni vor fork: %d\n\n", i);
pid = fork();
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0:
i++;
sprintf(str, "%d",i); // convert integer i to string str
retval = execl("./ChildProcA2.e", "ChildProcA2.e", str, NULL);
if (retval < 0) perror("\nexecl not successful");
break;
default:
i--;
printf("\n... wir sind die Eltern %d mit i=%d ", getpid(), i);
printf("und Kind %d,\n unsere Eltern sind %d\n", pid, getppid());
wait(&status);
break;
}
printf("\n. . . . . und wer bin ich ?\n\n");
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,34 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc
CMPFLAGS= -Wall
LDFLAGS=
EXENAME= ProcA2.e
FNAME= ProcA2
EXENAMC= ChildProcA2.e
FNAMC= ChildProcA2
LIBNAME=
LIBNAME=
compile: $(EXENAME) $(EXENAMC)
$(EXENAME): $(FNAME).o
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
$(EXENAMC): $(FNAMC).o
$(CMP) $(FNAMC).o $(LIBNAME) $(LDFLAGS) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f *.o $(EXENAME) $(EXENAMC)
all:
@make clean
@make

View File

@ -0,0 +1,31 @@
//***************************************************************************
// File: ProcA4.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
fork();
fork();
fork();
fork();
printf("PID: %d\t PPID: %d\n", getpid(), getppid());
sleep(10); // keep processes in system to display their "stammbaum"
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,27 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc
CMPFLAGS= -Wall
LDFLAGS=
EXENAMES= ProcA3.e
FNAME= ProcA3
LIBNAME=
$(EXENAMES): $(FNAME).o
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f *.o $(EXENAMES)
all:
@make clean
@make

View File

@ -0,0 +1,61 @@
//***************************************************************************
// File: ProcA5.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include "workerUtils.h"
#include "selectCPU.h"
#define ITERATIONS 20
#define WORK_HARD 2000000
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
pid_t pid;
int i;
pid = fork();
selectCPU(0); // select CPU 0
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0:
for (i = 0; i < ITERATIONS; i++) {
justWork(WORK_HARD);
printf("%d \t\tChild\n", i);
fflush(stdout); // force output
}
break;
default:
for (i = 0; i < ITERATIONS; i++) {;
justWork(WORK_HARD);
printf("%d \tMother\n", i);
fflush(stdout); // force output
}
}
printf("I go it ...\n");
if (pid > 0) // wait for child to terminate
waitpid(pid, NULL, 0);
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,2 @@
setCPU() does not work on OSX

View File

@ -0,0 +1,27 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc
CMPFLAGS= -Wall
LDFLAGS=
EXENAM1= ProcA4.e
FNAM1= ProcA4.o workerUtils.o selectCPU.o
LIBNAME=
$(EXENAM1): $(FNAM1)
$(CMP) $(FNAM1) $(LIBNAME) $(LDFLAGS) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f *.o $(EXENAM1)
all:
@make clean
@make

View File

@ -0,0 +1,41 @@
//***************************************************************************
// File: setCPU.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef __linux
#include <sched.h>
#endif
//******************************************************************************
#ifdef __linux
void selectCPU(unsigned int n) {
cpu_set_t cpuset;
if (n >= sysconf(_SC_NPROCESSORS_ONLN)) {
printf("CPU %d not availble\n", n);
exit(0);
}
sched_getaffinity(0, sizeof(cpu_set_t), &cpuset);
CPU_ZERO(&cpuset);
CPU_SET(n, &cpuset);
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
}
#endif
#ifdef __APPLE__
void selectCPU(unsigned int n) {
printf("Cannot set single CPU on OSX\n ... continue anyway");
}
#endif
//******************************************************************************

View File

@ -0,0 +1,15 @@
//*******************************************************************
// File: selectCPU.h
// Original Author: M. Thaler (Modul BSY)
//*******************************************************************
#ifndef SET_CPUS_HEADER_FILE
#define SET_CPUS_HEADER_FILE
//*******************************************************************
void selectCPU(unsigned int n);
//*******************************************************************
#endif

View File

@ -0,0 +1,90 @@
//*******************************************************************
// File: workerUtils.c
// Original Author: M. Thaler (Modul BSY)
// Purpose: helper applications to consume cpu time
//*******************************************************************
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include "workerUtils.h"
//------------------------------------------------------------------------------
#define MAX_CPUS 16
//------------------------------------------------------------------------------
pid_t worker[MAX_CPUS];
int nCPUS;
//------------------------------------------------------------------------------
void launchWorkLoad() {
int i;
nCPUS = sysconf(_SC_NPROCESSORS_ONLN); // get number of available CPUs
nCPUS = (nCPUS > MAX_CPUS) ? MAX_CPUS : nCPUS;
for (i = 0; i < nCPUS; i++) // start workers -> random load
worker[i] = startWorker();
}
void stopWorkLoad() {
int i;
for (i = 0; i < nCPUS; i++) // stop worker
stopWorker(worker[i]);
}
void setRandom(void) {
srandom((unsigned int)time(NULL)); // new random sequence
}
void justWork(unsigned int load) {
unsigned int j;
for (j = 0; j < load; j++) {}; // just work
}
void workHard(unsigned int low, unsigned int high) {
double rv;
unsigned int us, j;
high = high - low;
rv = ((double)random())/RAND_MAX; // make random value (0..1)
us = low + (unsigned int)(rv * high); // between lower & higher limit
for (j = 0; j < us; j++) {}; // just work
setRandom(); // reseed random generator
}
void randomSleep(unsigned int low, unsigned int high) {
double rv;
unsigned int us;
high = high - low;
rv = ((double)random())/RAND_MAX; // make random value (0..1)
us = low + (unsigned int)(rv * high); // between lower & higher limit
usleep(us*1000);
}
pid_t startWorker(void) { // make a hard working process
struct timeval tv; // limit run time to 60 secs
time_t st;
pid_t pid = fork();
if (pid == 0) { // child: pid = 0 -> ifinite loop
gettimeofday(&tv, NULL); // take start time
st = tv.tv_sec;
while ((tv.tv_sec-st) < 60) {
workHard(50, 800); // work hard (random interval
gettimeofday(&tv, NULL); // between 50us and 800us)
}
}
if (pid < 0) { // exit fork failed
printf("forking worker failed\n");
exit(0);
}
return pid; // return pid if parent
}
void stopWorker(pid_t worker) {
kill(worker, SIGKILL); // terminate worker process
}

View File

@ -0,0 +1,33 @@
//*******************************************************************
// File: workerUtils.h
// Original Author: M. Thaler (Modul BSY)
// Purpose: helper applications to consume cpu time
//*******************************************************************
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
//------------------------------------------------------------------------------
#define MAX_CPUS 16
//------------------------------------------------------------------------------
void launchWorkLoad();
void stopWorkLoad();
void setRandom(void);
void justWork(unsigned int load);
void workHard(unsigned int low, unsigned int high);
void randomSleep(unsigned int low, unsigned int high);
pid_t startWorker(void);
void stopWorker(pid_t worker);

View File

@ -0,0 +1,51 @@
//***************************************************************************
// File: ProcA6.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
pid_t pid, id;
char buf[64];
int i;
pid = fork();
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0:
printf("\n... ich bin das Kind %d\n", getpid());
for (i = 0; i < 10; i++) {
usleep(500000); // slow down a bit
printf("Mein Elternprozess ist %d\n", id = getppid());
}
printf("... so das wars\n");
break;
default:
sleep(2); // terminate
exit(0);
break;
}
printf("\n\n*** and here my new parent ****\n\n");
sprintf(buf, "ps -p %d", id);
system(buf);
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,3 @@
Reparenting -> new parent instead init (1):
command prctl(PR_SET_CHILD_SUBREAPER, 1)

View File

@ -0,0 +1,26 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc
CMPFLAGS= -Wall
LDFLAGS=
EXENAMES= ProcA5.e
FNAME= ProcA5
LIBNAME=
$(EXENAMES): $(FNAME).o
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f *.o $(EXENAMES)
all:
@make clean
@make

View File

@ -0,0 +1,48 @@
//***************************************************************************
// File: ProcA7.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
pid_t pid;
int j;
for (j = 0; j < 3; j++) { // generate 3 processes
pid = fork();
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0:
sleep(j+2); // process j sleeps for j+2 sec
exit(0); // then exits
break;
default: // parent
break;
}
}
sleep(8); // parent process sleeps for 6 sec
wait(NULL); // consult manual for "wait"
sleep(2);
wait(NULL);
sleep(2);
wait(NULL);
sleep(2);
exit(0);
}

View File

@ -0,0 +1,27 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc
CMPFLAGS= -Wall
LDFLAGS=
EXENAMES= aaaa.e
FNAME= ProcA6
LIBNAME=
$(EXENAMES): $(FNAME).o
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f *.o $(EXENAMES)
all:
@make clean
@make

View File

@ -0,0 +1,19 @@
#!/bin/bash
# M. Thaler, InIT/ZHAW 11/2014
# Version v.fs20
if test "$1" = ""
then
cmd="-a"
else
cmd="-C $1"
fi
forever="1"
while test "$forever" = "1"
do
clear
ps $cmd
sleep 1
done

View File

@ -0,0 +1,50 @@
//***************************************************************************
// File: ChildProcA8.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
//***************************************************************************
// Function: main(), parameter: arg[0]: Programmname, arg[1]: i
//***************************************************************************
int main(int argc, char *argv[]) {
int i = 0, *a = NULL;
if (argc > 1)
i = atoi(argv[1]); // convert string argv[1] to integer i
// argv[1] is a number passed to child
printf("\n*** I am the child having job nr. %d ***\n\n", i);
switch(i) {
case 0: exit(0); // exit normally
break;
case 1: *a = i; // force segmentation error
break;
case 2: kill(getpid(), 30); // I send signal 30 to myself
break;
case 3: sleep(5); // sleep and wait for signal
break;
case 4: sleep(5); // just sleep
exit(222); // then exit
break;
default:
exit(-1);
}
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,65 @@
//***************************************************************************
// File: ProcA8.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(int argc, char *argv[]) {
pid_t pid;
int status, retval, whatToDo = 0;
char str[8];
if (argc > 1)
whatToDo = atoi(argv[1]); // get job number for child
pid = fork(); // fork child
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0:
sprintf(str, "%d",whatToDo);
retval = execl("./ChildProcA7.e", "ChildProcA7.e", str, NULL);
if (retval < 0) perror("\nexecl not successful");
break;
default:
if (whatToDo <= 3) {
if (whatToDo == 3) {
sleep(1);
kill(pid, SIGABRT); // send signal SIGABTR to child
}
wait(&status);
if (WIFEXITED(status))
printf("Child exits with status %d\n", WEXITSTATUS(status));
if (WIFSIGNALED(status)) {
printf("Child exits on signal %d\n", WTERMSIG(status));
printf("Child exits with core dump %d\n", WCOREDUMP(status));
}
} else {
usleep(500*1000);
while (!waitpid(pid, &status, WNOHANG)) {
printf(". . . child is playing\n");
usleep(500*1000);
}
printf("Child has exited with 'exit(%d)'\n", WEXITSTATUS(status));
}
break;
}
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,21 @@
Enable core dumps -> ulimit -c unlimited
Disable core dumps -> ulimit -c 0
Das core File lesen mit gdb:
gdb -c core ChildProgA8.e
!!!! Wichtig !!!!
Wenn sie ein Linux benutzen, das standardmaessig ABRT (Automatic Bug
Reporting Tool) verwendet (z.B. Fedora, Centos, etc.), muss
/proc/sys/kernel/core_pattern auf "core" gesetzt werden, damit ein
core File erzeugt wird
echo core > /proc/sys/kernel/core_pattern
Wenn ihr System SE-Linux verwendet (z.B. Fedora) , laesst sich core_pattern
nicht auf einfache Art setzen, verzichten sie in diesem Fall auf die
Erzeugung des "core" Files.

View File

@ -0,0 +1,34 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc
CMPFLAGS= -Wall -g
LDFLAGS=
EXENAME= ProcA7.e
FNAME= ProcA7
EXENAMC= ChildProcA7.e
FNAMC= ChildProcA7
LIBNAME=
LIBNAME=
compile: $(EXENAME) $(EXENAMC)
$(EXENAME): $(FNAME).o
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
$(EXENAMC): $(FNAMC).o
$(CMP) $(FNAMC).o $(LIBNAME) $(LDFLAGS) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f core *.o $(EXENAME) $(EXENAMC)
all:
@make clean
@make

View File

@ -0,0 +1,45 @@
//***************************************************************************
// File: ProcA9_1.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
pid_t pid;
printf("\n");
printf("\nHallo, I am on the way to fork now, ......lo");
pid = fork();
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0:
printf("ok: I am the child\n");
break;
default:
printf("ok: I am the parent\n");
break;
}
printf("\nclear ?\n\n");
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,87 @@
//***************************************************************************
// File: ProcA9_2.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#define WAIT_TIME (200*1000) // 0.2 s with usleep
// globaler array
#define ARRAY_SIZE 8
char GArray[ARRAY_SIZE][ARRAY_SIZE];
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
pid_t pid;
int i,j;
// flip coin to select "child first" or "parent first"
struct timeval tv;
gettimeofday(&tv, NULL);
srandom(tv.tv_usec); // evaluate seed
int head = (int)(random()) >> 7; // flip coin
head &= 0x1;
// fill global array with '-' and print array value
for (i = 0; i < ARRAY_SIZE; i++) {
for (j = 0; j < ARRAY_SIZE; j++) {
GArray[i][j] = '-';
printf("%c ", GArray[i][j]);
}
printf("\n");
}
fflush(stdout);
pid = fork();
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0: // --- child fills upper half of array with 'c'
if (head) usleep(WAIT_TIME);
for (i = ARRAY_SIZE / 2; i < ARRAY_SIZE; i++)
for (j = 0; j < ARRAY_SIZE; j++)
GArray[i][j] = 'c';
break;
default: // --- parent fills lower half of array with 'p'
if (! head) usleep(WAIT_TIME);
for (i = 0; i < ARRAY_SIZE / 2; i++)
for (j = 0; j < ARRAY_SIZE; j++)
GArray[i][j] = 'p';
break;
}
if (pid == 0)
printf("\nKinderarray\n\n");
else
printf("\nElternarray\n\n");
for (i = 0; i < ARRAY_SIZE; i++) {
for (j = 0; j < ARRAY_SIZE; j++)
printf("%c ", GArray[i][j]);
printf("\n");
}
fflush(stdout);
if (pid > 0) wait(NULL);
exit(0);
}
//***************************************************************************

View File

@ -0,0 +1,74 @@
//***************************************************************************
// File: ProcA9_3.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sched.h>
#include "workerUtils.h"
#define ANZAHL 15
#define WORK_HARD 1000000
//*****************************************************************************
// Function: main(), parameter: none
//*****************************************************************************
int main(void) {
FILE *fdes;
pid_t pid;
int i;
launchWorkLoad(); // start CPU load to force context switches
fdes = fopen("AnyOutPut.txt", "w");
if (fdes == NULL) perror("Cannot open file");
usleep(500000);
pid = fork();
switch (pid) {
case -1:
perror("Could not fork");
break;
case 0:
for (i = 1; i <= ANZAHL; i++) {
fprintf(fdes, "Fritzli\t%d\n", i);
fflush(fdes); // make sure date is written to file
justWork(WORK_HARD);
}
break;
default:
for (i = 1; i <= ANZAHL; i++) {
fprintf(fdes, "Mami\t%d\n", i);
fflush(fdes); // make sure date is written to file
justWork(WORK_HARD);
}
fflush(stdout);
stopWorkLoad();
break;
}
printf("We are done\n");
if (pid > 0) {
waitpid(pid, NULL, 0);
printf("See file AnyOutPut.txt\n");
}
fflush(stdout);
exit(0);
}
//*****************************************************************************

View File

@ -0,0 +1,38 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc -std=gnu99
CMPFLAGS= -Wall
LDFLAGS=
EXENAME1= ProcA8_1.e
FNAM1= ProcA8_1.o
EXENAME2= ProcA8_2.e
FNAM2= ProcA8_2.o
EXENAME3= ProcA8_3.e
FNAM3= ProcA8_3.o workerUtils.o
LIBNAME=
compile: $(EXENAME1) $(EXENAME2) $(EXENAME3)
$(EXENAME1): $(FNAM1)
$(CMP) $(CMPFLAGS) $(FNAM1) $(LIBNAME) $(LDFLAGS) -o $@
$(EXENAME2): $(FNAM2)
$(CMP) $(CMPFLAGS) $(FNAM2) $(LIBNAME) $(LDFLAGS) -o $@
$(EXENAME3): $(FNAM3)
$(CMP) $(CMPFLAGS) $(FNAM3) $(LIBNAME) $(LDFLAGS) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f *.o $(EXENAME1) $(EXENAME2) $(EXENAME3)
all:
@make clean
@make

View File

@ -0,0 +1,90 @@
//*******************************************************************
// File workerUtils.c
// Original Author: M. Thaler (Modul BSY)
// Purpose: helper applications to consume cpu time
//*******************************************************************
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include "workerUtils.h"
//------------------------------------------------------------------------------
#define MAX_CPUS 16
//------------------------------------------------------------------------------
pid_t worker[MAX_CPUS];
int nCPUS;
//------------------------------------------------------------------------------
void launchWorkLoad() {
int i;
nCPUS = sysconf(_SC_NPROCESSORS_ONLN); // get number of available CPUs
nCPUS = (nCPUS > MAX_CPUS) ? MAX_CPUS : nCPUS;
for (i = 0; i < nCPUS; i++) // start workers -> random load
worker[i] = startWorker();
}
void stopWorkLoad() {
int i;
for (i = 0; i < nCPUS; i++) // stop worker
stopWorker(worker[i]);
}
void setRandom(void) {
srandom((unsigned int)time(NULL)); // new random sequence
}
void justWork(unsigned int load) {
unsigned int j;
for (j = 0; j < load; j++) {}; // just work
}
void workHard(unsigned int low, unsigned int high) {
double rv;
unsigned int us, j;
high = high - low;
rv = ((double)random())/RAND_MAX; // make random value (0..1)
us = low + (unsigned int)(rv * high); // between lower & higher limit
for (j = 0; j < us; j++) {}; // just work
setRandom(); // reseed random generator
}
void randomSleep(unsigned int low, unsigned int high) {
double rv;
unsigned int us;
high = high - low;
rv = ((double)random())/RAND_MAX; // make random value (0..1)
us = low + (unsigned int)(rv * high); // between lower & higher limit
usleep(us*1000);
}
pid_t startWorker(void) { // make a hard working process
struct timeval tv; // limit run time to 60 secs
time_t st;
pid_t pid = fork();
if (pid == 0) { // child: pid = 0 -> ifinite loop
gettimeofday(&tv, NULL); // take start time
st = tv.tv_sec;
while ((tv.tv_sec-st) < 60) {
workHard(50, 800); // work hard (random interval
gettimeofday(&tv, NULL); // between 50us and 800us)
}
}
if (pid < 0) { // exit fork failed
printf("forking worker failed\n");
exit(0);
}
return pid; // return pid if parent
}
void stopWorker(pid_t worker) {
kill(worker, SIGKILL); // terminate worker process
}

View File

@ -0,0 +1,25 @@
//*******************************************************************
// File: workerUtils.h
// Original Author: M. Thaler (Modul BSY)
//*******************************************************************
#ifndef WORKER_UTILS
#define WORKER_UTILS
void launchWorkLoad();
void stopWorkLoad();
void setRandom(void);
void justWork(unsigned int load);
void workHard(unsigned int low, unsigned int high);
void randomSleep(unsigned int low, unsigned int high);
pid_t startWorker(void);
void stopWorker(pid_t worker);
#endif

View File

@ -0,0 +1,112 @@
//***************************************************************************
// File: ProcA9.c
// Original Author: M. Thaler (Modul BSY)
//***************************************************************************
//***************************************************************************
// system includes
//***************************************************************************
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include "selectCPU.h"
//**************************************************************************
// global data
#define ARRAY_SIZE 8
char GArray[ARRAY_SIZE][ARRAY_SIZE];
//**************************************************************************
void *ThreadF(void *letter) {
int i,j;
int LowLim, HighLim;
char letr;
letr = *(char *)letter;
if (letr == 'p') { // paremeter = p: fill lower half of array
LowLim = 0; HighLim = ARRAY_SIZE / 2;
}
else { // paremeter != p: fill upper half of array
LowLim = ARRAY_SIZE / 2; HighLim = ARRAY_SIZE;
}
for (i = LowLim; i < HighLim; i++) { // fill own half
for (j = 0; j < ARRAY_SIZE; j++)
GArray[i][j] = letr;
}
for (i = 0; i < ARRAY_SIZE; i++) { // print whole array
for (j = 0; j < ARRAY_SIZE; j++)
printf("%c ", GArray[i][j]);
printf("\n");
}
printf("\n");
fflush(stdout);
pthread_exit(0);
}
//***************************************************************************
// Function: main(), parameter: none
//***************************************************************************
int main(void) {
pthread_t thread1, thread2;
int i,j, pthr;
char letter1, letter2;
selectCPU(0); // run on CPU 0
// flip coin to select p or c first
struct timeval tv;
gettimeofday(&tv, NULL);
srandom(tv.tv_usec); // evaluate seed
int head = (int)(random()) >> 7; // flip coin
head &= 0x1;
if (head) {
letter1 = 'p';
letter2 = 'c';
}
else {
letter1 = 'c';
letter2 = 'p';
}
for (i = 0; i < ARRAY_SIZE; i++)
for (j = 0; j < ARRAY_SIZE; j++)
GArray[i][j] = '-';
printf("\nArray vor Threads\n\n");
for (i = 0; i < ARRAY_SIZE; i++) {
for (j = 0; j < ARRAY_SIZE; j++)
printf("%c ", GArray[i][j]);
printf("\n");
}
printf("\n");
pthr = pthread_create(&thread1, NULL, ThreadF, (void *)&letter1);
if (pthr != 0) perror("Could not create thread");
pthr = pthread_create(&thread2, NULL, ThreadF, (void *)&letter2);
if (pthr != 0) perror("Could not create thread");
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("\n... nach Threads\n");
for (i = 0; i < ARRAY_SIZE; i++) {
for (j = 0; j < ARRAY_SIZE; j++)
printf("%c ", GArray[i][j]);
printf("\n");
}
}
//***************************************************************************

View File

@ -0,0 +1,27 @@
# *************************************************************
# Original Autor: M. Thaler (Modul BSY)
# *************************************************************
CMP= gcc -std=gnu99 -pthread
CMPFLAGS= -Wall
LDFLAGS=
EXENAME1= ProcA9.e
FNAM1= ProcA9.o selectCPU.o
LIBNAME=
$(EXENAME1): $(FNAM1)
$(CMP) $(FNAM1) $(LDFLAGS) $(LIBNAME) -o $@
.c.o:
$(CMP) -c $(CMPFLAGS) $<
.cc.o:
$(CMP) -c $(CMPFLAGS) $<
clean:
rm -f *.o $(EXENAME1)
all:
@make clean
@make

View File

@ -0,0 +1,41 @@
//******************************************************************************
// File: setCPU.c
// Original Author: M. Thaler (Modul BSY)
//******************************************************************************
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef __linux
#include <sched.h>
#endif
//******************************************************************************
#ifdef __linux
void selectCPU(unsigned int n) {
cpu_set_t cpuset;
if (n >= sysconf(_SC_NPROCESSORS_ONLN)) {
printf("CPU %d not availble\n", n);
exit(0);
}
sched_getaffinity(0, sizeof(cpu_set_t), &cpuset);
CPU_ZERO(&cpuset);
CPU_SET(n, &cpuset);
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
}
#endif
#ifdef __APPLE__
void selectCPU(unsigned int n) {
printf("Cannot set single CPU on OSX\n ... continue anyway");
}
#endif
//******************************************************************************

View File

@ -0,0 +1,15 @@
//******************************************************************************
// File: setCPU.h
// Original Author: M. Thaler (Modul BSY)
//******************************************************************************
#ifndef SET_CPUS_HEADER_FILE
#define SET_CPUS_HEADER_FILE
//******************************************************************************
void selectCPU(unsigned int n);
//******************************************************************************
#endif