diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/Daemonizer.c b/P09_Prozesse_und_Threads/Daemon_Prozesse/Daemonizer.c new file mode 100644 index 0000000..5209c01 --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/Daemonizer.c @@ -0,0 +1,178 @@ +/****************************************************************************** +* File: Daemonizer.c +* Original Autor: M. Thaler (Modul BSY) +* Aufgabe: Einen Daemon-Prozess erzeugen +******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//***************************************************************************** + +// 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); +} + +//***************************************************************************** diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/Daemonizer.h b/P09_Prozesse_und_Threads/Daemon_Prozesse/Daemonizer.h new file mode 100644 index 0000000..3f03fab --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/Daemonizer.h @@ -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 + +//------------------------------------------------------------------------ diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/IPsockCom.c b/P09_Prozesse_und_Threads/Daemon_Prozesse/IPsockCom.c new file mode 100644 index 0000000..af35c9f --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/IPsockCom.c @@ -0,0 +1,188 @@ +//***************************************************************************** +// ipCom.c IP Socket Functions +// Original Author: M. Thaler, M. Pellaton (Modul BSY) +//***************************************************************************** + +//***************************************************************************** +// system includes +//***************************************************************************** + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +//***************************************************************************** +// 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); +} + +//***************************************************************************** diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/IPsockCom.h b/P09_Prozesse_und_Threads/Daemon_Prozesse/IPsockCom.h new file mode 100644 index 0000000..1fb8c83 --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/IPsockCom.h @@ -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 + +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/MrTimeDaemon.c b/P09_Prozesse_und_Threads/Daemon_Prozesse/MrTimeDaemon.c new file mode 100644 index 0000000..f84926f --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/MrTimeDaemon.c @@ -0,0 +1,44 @@ +/********************************************************************* +* File: MrTimeDaemon.c +* Original Autor: M. Thaler (Modul BSY) +* Aufgabe: einen Daemon-Prozess erzeugen +*********************************************************************/ + +#include +#include +#include +#include +#include +#include + +#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"); + } + +} + +//-------------------------------------------------------------------- diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/PlapperMaul.c b/P09_Prozesse_und_Threads/Daemon_Prozesse/PlapperMaul.c new file mode 100644 index 0000000..2a2db97 --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/PlapperMaul.c @@ -0,0 +1,21 @@ +/********************************************************************* +* File: PlapperMaul.c +* Original Autor: M. Thaler (Modul BSY) +* Aufgabe: plappern +*********************************************************************/ + +#include +#include +#include + +//-------------------------------------------------------------------- + +int main(void) { + + while (1) { + printf("Hallo, ich bins.... Pidi %d\n", getpid()); + usleep(500000); + } +} + +//-------------------------------------------------------------------- diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemon.c b/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemon.c new file mode 100644 index 0000000..fcbc568 --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemon.c @@ -0,0 +1,75 @@ +/****************************************************************************** +* File: TimeDaemon.c +* Original Autor: M. Thaler (Modul BSY) +* Aufgabe: the daemon code +******************************************************************************/ + +//***************************************************************************** +// system includes +//***************************************************************************** + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//***************************************************************************** +// 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); +} + +//***************************************************************************** diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemon.h b/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemon.h new file mode 100644 index 0000000..ddc898a --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemon.h @@ -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 + +//***************************************************************************** diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemonDefs.h b/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemonDefs.h new file mode 100644 index 0000000..d29f19d --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/TimeDaemonDefs.h @@ -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 + +//***************************************************************************** diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/WhatsTheTimeMr.c b/P09_Prozesse_und_Threads/Daemon_Prozesse/WhatsTheTimeMr.c new file mode 100644 index 0000000..5180382 --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/WhatsTheTimeMr.c @@ -0,0 +1,66 @@ +/****************************************************************************** +* File: WhatsTheTimeMr.c +* Original Autor: M. Thaler (Modul BSY) +* Aufgabe: Ask MrTimeDaemon for the time +******************************************************************************/ + +//***************************************************************************** +// system includes +//***************************************************************************** + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // 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); +} + +//***************************************************************************** + diff --git a/P09_Prozesse_und_Threads/Daemon_Prozesse/makefile b/P09_Prozesse_und_Threads/Daemon_Prozesse/makefile new file mode 100644 index 0000000..32af073 --- /dev/null +++ b/P09_Prozesse_und_Threads/Daemon_Prozesse/makefile @@ -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 diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe01/ProcA1.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe01/ProcA1.c new file mode 100644 index 0000000..9b37481 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe01/ProcA1.c @@ -0,0 +1,53 @@ +//*************************************************************************** +// File: ProcA1.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} + +//*************************************************************************** + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe01/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe01/makefile new file mode 100644 index 0000000..fa951bf --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe01/makefile @@ -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 diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/ChildProcA2.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/ChildProcA2.c new file mode 100644 index 0000000..470bcde --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/ChildProcA2.c @@ -0,0 +1,38 @@ +//*************************************************************************** +// File: ChildProcA3.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} + +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/ProcA2.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/ProcA2.c new file mode 100644 index 0000000..1120825 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/ProcA2.c @@ -0,0 +1,54 @@ +//*************************************************************************** +// File: ProcA3.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} + +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/makefile new file mode 100644 index 0000000..4d23435 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe02/makefile @@ -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 diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe03/ProcA3.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe03/ProcA3.c new file mode 100644 index 0000000..3c29605 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe03/ProcA3.c @@ -0,0 +1,31 @@ +//*************************************************************************** +// File: ProcA4.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} + +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe03/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe03/makefile new file mode 100644 index 0000000..af2c854 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe03/makefile @@ -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 + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/ProcA4.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/ProcA4.c new file mode 100644 index 0000000..0554662 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/ProcA4.c @@ -0,0 +1,61 @@ +//*************************************************************************** +// File: ProcA5.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include +#include + +#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); +} +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/README_MAC b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/README_MAC new file mode 100644 index 0000000..84bd483 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/README_MAC @@ -0,0 +1,2 @@ + +setCPU() does not work on OSX diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/makefile new file mode 100644 index 0000000..8bc8dbd --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/makefile @@ -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 + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/selectCPU.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/selectCPU.c new file mode 100644 index 0000000..8f5ddee --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/selectCPU.c @@ -0,0 +1,41 @@ +//*************************************************************************** +// File: setCPU.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +#define _GNU_SOURCE + +#include +#include +#include +#include + +#ifdef __linux +#include +#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 + +//****************************************************************************** + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/selectCPU.h b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/selectCPU.h new file mode 100644 index 0000000..87067b9 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/selectCPU.h @@ -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 diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/workerUtils.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/workerUtils.c new file mode 100644 index 0000000..85368a0 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/workerUtils.c @@ -0,0 +1,90 @@ +//******************************************************************* +// File: workerUtils.c +// Original Author: M. Thaler (Modul BSY) +// Purpose: helper applications to consume cpu time +//******************************************************************* + +#include +#include +#include +#include +#include +#include +#include + +#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 +} diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/workerUtils.h b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/workerUtils.h new file mode 100644 index 0000000..ac5226f --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe04/workerUtils.h @@ -0,0 +1,33 @@ +//******************************************************************* +// File: workerUtils.h +// Original Author: M. Thaler (Modul BSY) +// Purpose: helper applications to consume cpu time +//******************************************************************* + +#include +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +#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); diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/ProcA5.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/ProcA5.c new file mode 100644 index 0000000..a73c979 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/ProcA5.c @@ -0,0 +1,51 @@ +//*************************************************************************** +// File: ProcA6.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} + +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/README b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/README new file mode 100644 index 0000000..23988f6 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/README @@ -0,0 +1,3 @@ +Reparenting -> new parent instead init (1): + +command prctl(PR_SET_CHILD_SUBREAPER, 1) diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/makefile new file mode 100644 index 0000000..00e05fc --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe05/makefile @@ -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 diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/ProcA6.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/ProcA6.c new file mode 100644 index 0000000..f5bb59f --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/ProcA6.c @@ -0,0 +1,48 @@ +//*************************************************************************** +// File: ProcA7.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/makefile new file mode 100644 index 0000000..f802333 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/makefile @@ -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 + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/mtop b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/mtop new file mode 100755 index 0000000..04949bb --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe06/mtop @@ -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 + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/ChildProcA7.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/ChildProcA7.c new file mode 100644 index 0000000..635d098 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/ChildProcA7.c @@ -0,0 +1,50 @@ +//*************************************************************************** +// File: ChildProcA8.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} + +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/ProcA7.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/ProcA7.c new file mode 100644 index 0000000..06b8cfd --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/ProcA7.c @@ -0,0 +1,65 @@ +//*************************************************************************** +// File: ProcA8.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} + +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/README b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/README new file mode 100644 index 0000000..9f27733 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/README @@ -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. diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/makefile new file mode 100644 index 0000000..6d8bc93 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe07/makefile @@ -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 diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_1.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_1.c new file mode 100644 index 0000000..5fbe822 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_1.c @@ -0,0 +1,45 @@ +//*************************************************************************** +// File: ProcA9_1.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include + +//*************************************************************************** +// 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); +} + +//*************************************************************************** + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_2.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_2.c new file mode 100644 index 0000000..a3bbdff --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_2.c @@ -0,0 +1,87 @@ +//*************************************************************************** +// File: ProcA9_2.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include +#include + +#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); +} + +//*************************************************************************** diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_3.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_3.c new file mode 100644 index 0000000..b2786bc --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/ProcA8_3.c @@ -0,0 +1,74 @@ +//*************************************************************************** +// File: ProcA9_3.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include +#include + + +#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); +} + +//***************************************************************************** + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/makefile new file mode 100644 index 0000000..e5921ff --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/makefile @@ -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 diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/workerUtils.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/workerUtils.c new file mode 100644 index 0000000..1fb8a5d --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/workerUtils.c @@ -0,0 +1,90 @@ +//******************************************************************* +// File workerUtils.c +// Original Author: M. Thaler (Modul BSY) +// Purpose: helper applications to consume cpu time +//******************************************************************* + +#include +#include +#include +#include +#include +#include +#include + +#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 +} diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/workerUtils.h b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/workerUtils.h new file mode 100644 index 0000000..c944cda --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe08/workerUtils.h @@ -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 diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/ProcA9.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/ProcA9.c new file mode 100644 index 0000000..ded9dad --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/ProcA9.c @@ -0,0 +1,112 @@ +//*************************************************************************** +// File: ProcA9.c +// Original Author: M. Thaler (Modul BSY) +//*************************************************************************** + +//*************************************************************************** +// system includes +//*************************************************************************** + +#include +#include +#include +#include +#include +#include +#include +#include + +#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"); + } +} + +//*************************************************************************** + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/makefile b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/makefile new file mode 100644 index 0000000..f29cbb6 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/makefile @@ -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 + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/selectCPU.c b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/selectCPU.c new file mode 100644 index 0000000..ad67886 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/selectCPU.c @@ -0,0 +1,41 @@ +//****************************************************************************** +// File: setCPU.c +// Original Author: M. Thaler (Modul BSY) +//****************************************************************************** + +#define _GNU_SOURCE + +#include +#include +#include +#include + +#ifdef __linux +#include +#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 + +//****************************************************************************** + diff --git a/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/selectCPU.h b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/selectCPU.h new file mode 100644 index 0000000..1079489 --- /dev/null +++ b/P09_Prozesse_und_Threads/Prozesse_und_Threads/Aufgabe09/selectCPU.h @@ -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