Skip to content

Instantly share code, notes, and snippets.

@mfurquimdev
Created August 16, 2014 21:19
Show Gist options
  • Save mfurquimdev/e77f9db907b353ff2589 to your computer and use it in GitHub Desktop.
Save mfurquimdev/e77f9db907b353ff2589 to your computer and use it in GitHub Desktop.
Operating System Tutorials
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#define N 5 // The number of producers/customers
#define M 10 // The size of the buffer
int in = 0; // The index for the producer to put
int out = 0; // Where the customer to consume
int buff[M] = { 0 }; // Initialization, 0 as no products
sem_t empty_sem; // synchronization semaphore, block producers when 0
sem_t full_sem; // synchronization semaphore, block customers when full
pthread_mutex_t mutex; // mutual exclusive semaphore, one thread to gain access to buffer at one time
int product_id = 0; // ID for producers
int consume_id = 0; // ID for customers
/* Print buffer information */
void print() {
//inti;
printf("The buffer: ");
int i;
for( i = 0; i < M; i++) // error: loop initial declarations are only allowed in C99 mode
printf("%d", buff[i]);
printf("\n");
}
/* Function for producers */
void *product() {
int id = ++product_id;
while(1) {// Repeat
// Schedule the working speed of producers/customers, to easier observation
//sleep(2);
sem_wait(&empty_sem);
pthread_mutex_lock(&mutex);
in= in % M;
printf("Producer %d puts Product %d in the buffer\t",id, in);
buff[in]= 1;
print();
++in;
pthread_mutex_unlock(&mutex);
sem_post(&full_sem);
}
}
/* Function for customers */
void *consume() {
int id = ++consume_id;
while(1) {// Repeat
// Schedule the working speed of producers/customers, to easier observation
//sleep(2);
sem_wait(&full_sem);
pthread_mutex_lock(&mutex);
out= out % M;
printf("Customer %d consumes Product %d from the buffer\t",id, out);
buff[out]= 0;
print();
++out;
pthread_mutex_unlock(&mutex);
sem_post(&empty_sem);
}
}
int main() {
printf("5 Producers and 5 Consumers, Buffer size 10, Producers generate a product every 2 seconds,Customers consume a product every 2 seconds,Ctrl+C Exit the program\n");
/* Test Color Highlights
printf("\033[31m The ......\n\033[0m");
printf("\033[2;7;1mHEOO.\n\033[2;7;0m");
printf("\033[41;36msomthe here\n\033[0m");
*/
pthread_t id1[N];
pthread_t id2[N];
int i;
int ret[N];
// Initialize the semaphores
int ini1 = sem_init(&empty_sem, 0, M); //
int ini2 = sem_init(&full_sem, 0, 0); //
// ini1 = 1;
if(ini1 != 0 || ini2 != 0) {
printf("Fail to initialize the semaphores.\n");
exit(1);
}
// Initialize the mutex
int ini3 = pthread_mutex_init(&mutex, NULL);
if(ini3 != 0) {
printf("Fail to initialize the mutex.\n");
exit(1);
}
// Create N Producers
for(i = 0; i < N; i++) {
ret[i]= pthread_create(&id1[i], NULL, product, (void *) (&i));
if(ret[i] != 0) {
printf("Producer %d Creation Fails.\n", i);
exit(1);
}
}
// Create N Customers
for(i = 0; i < N; i++) {
ret[i]= pthread_create(&id2[i], NULL, consume, NULL);
if(ret[i] != 0) {
printf("Customer %d Creation Fails.\n", i);
exit(1);
}
}
// Wait for the termination of threads (Producers/Customers)
for(i = 0; i < N; i++) {
pthread_join(id1[i], NULL);
pthread_join(id2[i],NULL);
}
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void*print_sth(void *);
int main()
{
pthread_t thread1;
char *message1 = "Hello thread";
pthread_create( &thread1, NULL, print_sth,
(void*) message1);
pthread_join(thread1, NULL);
printf("Thread 1 finished.\n");
return 0;
}
void *print_sth( void *ptr ) {
char* message;
message = (char*)ptr;
printf("%s\n",message);
return NULL;
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
void*print_sth(void *);
int main()
{
pthread_t thread1;
char *message1 = "Hello thread";
int err = pthread_create( &thread1, NULL, print_sth,
(void*) message1);
perror("My custom message");
if (err != 0) {
fprintf(stderr, "can't create thread: %s\n", strerror(err));
exit(1);
}
pthread_join(thread1, NULL);
printf("Thread 1 finished.\n");
return 0;
}
void *print_sth( void *ptr ) {
char* message;
message = (char*)ptr;
printf("%s\n",message);
return NULL;
}
#include <stdio.h>
int main ()
{
FILE *fp;
/* first rename if there is any file */
rename("file.txt", "newfile.txt");
/* now let's try to open same file */
fp = fopen("file.txt", "r");
if ( fp == NULL ) {
perror("File Open Error ");
return(-1);
}
fclose(fp);
return(0);
}
#include<stdio.h>;
#include<pthread.h>;
#include <unistd.h>; //if you forget what to include, check man page for the function
void * thread_function(void * ptr)
{
while (1) {
printf(".");
// usleep(10); //1sec
}
pthread_exit(0);
}
int main()
{
pthread_t tid;
pthread_create(&tid, 0, thread_function, 0);
usleep(5000000); // 10secs
pthread_cancel(tid);
pthread_join(tid, 0);
return 0;
}
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#define M 3
#define N 3
#define P 3
int A[M][N]={
{-9, 7, -1},
{6, -5, 2},
{6, -4, 1}
};
int B[N][P]={
{1, -1, 3},
{2, -1, 4},
{2, 2, 1}
};
int C[M][P]={
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
};
void *matmult(void *);
int main( ) {
int i,j;
pthread_t thr[M];
int error;
for (i=0; i<M; i++) { /* create the worker threads */
if ((error = pthread_create(
&thr[i],
0,
matmult,
(void *)i)) != 0)
{
fprintf(stderr, "pthread_create: %s",
strerror(error));
exit(1);
}
}
for (i=0; i<M; i++) { /* wait for workers to finish their jobs */
pthread_join(thr[i], 0);
}
/* print the results*/
for (i = 0; i < M; i++) {
for (j = 0; j < P; j++) {
printf("%d ", C[i][j]);
}
printf("\n");
}
return 0;
}
void *matmult (void *arg) {
int row = (int)arg;
int col;
int i;
int t;
for (col=0; col < P; col++) {
t = 0;
for (i=0; i<N; i++) {
t += A[row][i] * B[i][col];
}
C[row][col] = t;
}
return(0);
}
#include <sys/wait.h>
# include <stdio.h>
# include <unistd.h>
#include<stdlib.h>
int main(void)
{
char *const parmList[] = {"ls", "-l", NULL};
pid_t pid = fork();
if (pid == 0) {
if (execv("/bin/ls", parmList) < 0){
perror("Error on execv.");
}
}
else {
while(pid != wait(0));
return 0;
}
}
#include <sys/stat.h>
#include <unistd.h>
#include<stdio.h>;
#include<stdlib.h>;
#include<string.h>;
int main() {
char* f = "/a.out";
char* cwd = (char*) malloc(sizeof(char) * 100);
getcwd(cwd, 100);
f = strcat(cwd, f);
printf("%s",f);
struct stat fileStat;
if(stat(f,&fileStat) < 0)
{
return 1;
}
printf("Information for %s\n",f);
printf("---------------------------\n");
printf("File Size: \t\t%d bytes\n",fileStat.st_size);
printf("Number of Links: \t%d\n",fileStat.st_nlink);
printf("File inode: \t\t%d\n",fileStat.st_ino);
printf("File Permissions: \t");
printf( (S_ISDIR(fileStat.st_mode)) ? "d" : "-");
printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");
printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");
printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");
printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");
printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");
printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");
printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");
printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");
printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");
}
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int main() {
int i;
printf("I'm before fork process.\n"); // Code for parent's behavior
fflush(stdout);
pid_t retValue = fork(); // Call of fork() in parent process
if(retValue == 0) // Child gets '0' as the return value of fork()
{
printf("I'm child process.\n"); // Code for child's behavior
}
else if (retValue > 0) // Parent gets the pid of child
{
printf("I'm parent process.\n"); // Code for parent's behavior
waitpid(retValue, NULL, 0);
return 0;
}
else // Otherwise, it fails to create new proces
{
printf("Creating Fails."); // Check errors
}
}
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
//void Handlesignal(int);
int main() {
int i;
printf("I'm before fork process.\n"); // Code for parent's behavior
fflush(stdout);
pid_t retValue = fork(); // Call of fork() in parent process
if(retValue == 0) // Child gets '0' as the return value of fork()
{
printf("I'm child process.\n"); // Code for child's behavior
}
else if (retValue > 0) // Parent gets the pid of child
{
printf("I'm parent process.\n"); // Code for parent's behavior
}
else // Otherwise, it fails to create new proces
{
printf("Creating Fails."); // Check errors
}
}
#include<stdlib.h>;
#include<stdio.h>;
#include<stdbool.h>;
typedef struct node
{
int item ;
struct node * next ;
} Node ;
Node* tail = NULL;
Node* head = NULL;
void push(int);
int pop();
bool isEmpty();
int main() {
push(1);
push(2);
if (!isEmpty()) {
printf("Item removed: %d\n", pop());
}
push(3);
if (!isEmpty()) {
printf("Item removed: %d\n", pop());
}
}
bool isEmpty() {
return head == NULL;
}
void push(int v) {
Node* newNode = (Node*) malloc (sizeof(Node));
newNode->item = v;
newNode->next = NULL;
if (isEmpty()) {
head = newNode;
tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
}
int pop() {
if (head == NULL) {
exit(1);
}
Node * tmp = head;
head = head->next;
int v = tmp->item;
free(tmp);
return v;
}
#include<stdlib.h>
typedef struct Node {
int item; //could be anything-e.g. Task, Process, etc.
struct Node* left;
struct Node* right;
} Node;
Node* heap;
Node* root1;
Node* root2;
Node* addNode(Node*);
Node* merge (Node*, Node*);
int remove ();
void initMyHeap();
Node* makeNode(int );
int main() {
initMyHeap();
heap = merge(root1, root2);
addNode(makeNode(4));
while (1) {
printf("%d\n", remove());
}
}
int remove () {
if (heap == NULL) {
exit(1);
}
Node* tmp = heap;
heap = merge(heap->right, heap->left);
int v = tmp->item;
free(tmp);
return v;
}
Node* addNode(Node* newNode) {
heap = merge(heap, newNode);
return heap;
}
Node* merge (Node* h1, Node* h2) {
if (h1 == NULL) return h2;
if (h2 == NULL) return h1;
if (h1->item < h2->item) {
Node* temp = h1->left;
h1->left = merge(h1->right, h2);
h1->right = temp;
return h1;
} else {
Node* temp = h2->right;
h2->right = merge(h2->left, h1);
h2->left = temp;
return h2;
}
}
/*
*Initializes two heaps
*/
void initMyHeap() {
root1 = makeNode(1);
root1->left = makeNode(3);
root1->right = makeNode(5);
root2 = makeNode(2);
root2->left = makeNode(6);
root2->right = makeNode(7);
}
/**
* Creates a heap node with the given value
*/
Node* makeNode(int v) {
Node* tmp = (Node*) malloc(sizeof(Node));
tmp->item = v;
tmp->right = NULL;
tmp->left = NULL;
return tmp;
}
#include <sys/wait.h>
# include <stdio.h>
# include <unistd.h>
#include<stdlib.h>
int main(void)
{
int pipeFD[2];
pid_t pid_A, pid_B;
pipe(pipeFD);
if( !(pid_A = fork()) ) {
close(1);
dup(pipeFD[1]); /* redirect standard output to pipe_A write end */
close(pipeFD[1]);
close(pipeFD[0]);
char *const parmList[] = {"ls", "-l", NULL};
execv("/bin/ls", parmList);
}
if( !(pid_B = fork()) ) {
close(0);
dup(pipeFD[0]); /* redirect standard input to pipe_A read end */
close(pipeFD[1]);
close(pipeFD[0]);
char *const pList[] = {"grep", "out", NULL};
execvp("grep", pList);
}
close(pipeFD[0]);
close(pipeFD[1]);
waitpid(pid_A, NULL, 0);
waitpid(pid_B, NULL, 0);
return;
}
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
char *argvv[2][3] = { { "ls", 0, 0}, { "grep", "a", 0 } };
int status;
int fd[2];
pipe(fd);
if ((pid = fork()) != -1) {
if(pid == 0){ /*Child executing */
close(fd[0]);
close(1);
dup(fd[1]);
close(fd[1]);
execvp(argvv[0][0], argvv[0]); /* Here's stored the first instruction */
} else{ /* Parent executing */
// wait(&status);
close(fd[1]);
close(0);
dup(fd[0]);
close(fd[0]);
execvp(argvv[1][0], argvv[1]); /* Here's stored the second instruction */
}
}
return 0;
}
#include <stdio.h>
int main(void)
{
FILE *pipein_fp, *pipeout_fp;
char readbuf[80];
/* Create one way pipe line with call to popen() */
if (( pipein_fp = popen("ls -l", "r")) == NULL)
{
perror("popen");
exit(1);
}
/* Create one way pipe line with call to popen() */
if (( pipeout_fp = popen("grep a.out", "w")) == NULL)
{
perror("popen");
exit(1);
}
/* Processing loop */
while(fgets(readbuf, 80, pipein_fp))
fputs(readbuf, pipeout_fp);
/* Close the pipes */
pclose(pipein_fp);
pclose(pipeout_fp);
return(0);
}
#include<stdio.h>;
int main() {
char readbuf[500];
FILE* pipein_fp = popen("ls -l | grep a.out", "r");
while(fgets(readbuf, 500, pipein_fp)) {
printf("%s", readbuf);
}
return 0;
}
#include <stdio.h>
int main() {
FILE *fp;
int status;
char path[1000];
fp = popen("ls -l *", "r");
while (fgets(path, 1000, fp)) {
printf("%s", path);
}
pclose(fp);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
void write_data (FILE * stream)
{
int i;
for (i = 0; i < 100; i++)
fprintf (stream, "%d\n", i);
if (ferror (stream))
{
fprintf (stderr, "Output to stream failed.\n");
exit (EXIT_FAILURE);
}
}
int main (void)
{
FILE *output;
output = popen ("more", "w");
if (!output)
{
fprintf (stderr,
"incorrect parameters or too many files.\n");
return EXIT_FAILURE;
}
write_data (output);
if (pclose (output) != 0)
{
fprintf (stderr,
"Could not run more or other error.\n");
}
return EXIT_SUCCESS;
}
/* Example of using sigaction() to setup a signal handler with only 1 argument. */
/* Compile.
$./a.out & ('&' to Background processing) Record the PID of the process
$ kill PID (It should print "test\n")
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
static void hdl (int sig)
{
printf("received signal %d\n", sig);
}
int main (int argc, char *argv[])
{
struct sigaction act;
memset (&act, '\0', sizeof(act));
act.sa_handler = hdl;
if (sigaction(SIGINT, &act, NULL) < 0||
sigaction(SIGTERM, &act, NULL) < 0) {
perror ("sigaction");
return 1;
}
printf("\nPARENT: Here's my PID: %d\n", getpid());
while (1)
sleep (10);
return 0;
}
/* Example of using sigaction() to setup a signal handler with 3 arguments
* including siginfo_t.
* http://www.linuxprogrammingblog.com/code-examples/sigaction
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
static void hdl (int sig, siginfo_t *siginfo, void *context)
{
printf("Here's my PID: %d\n", getpid());
printf ("Sending signal %d from PID: %ld, UID: %ld\n",
sig, (long)siginfo->si_pid, (long)siginfo->si_uid);
}
int main (int argc, char *argv[])
{
struct sigaction act;
memset (&act, '\0', sizeof(act));
/* Use the sa_sigaction field because the handles has two additional parameters */
act.sa_sigaction = &hdl;
/* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGTERM, &act, NULL) < 0) {
perror ("sigaction");
return 1;
}
printf("\nPARENT: Here's my PID: %d\n", getpid());
while (1)
sleep (10);
return 0;
}
/* Simplest dead child cleanup in a SIGCHLD handler. Prevent zombie (child) processes
* and print basic information (PID) about them.
*/
/* SIGCHLD is sent by a child process when it returns normally.
* In parent process, we use sigaction() to register SIGCHLD with a handler function.
* When the parent receives (captures) SIGCHLD signal, it stops its current job (waiting user's input),
* and calls the handler function. Once it is done, the parent returns to the previous job.
* Without sigaction(), SIGCHLD signal is simply ignored by the parent process.
*/
/* Check zombie process
* Use 'ps' command with options like:
* $ ps -aux | grep Z
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
/* SIGCHLD handler: sa_sigaction */
static void sigchld_hdl_action (int sig, siginfo_t *siginfo, void *context)
{
/* Wait for all dead processes.
* We use a non-blocking call to be sure this signal handler will not
* block if a child was cleaned up in another part of the program.
*/
pid_t t;
t = waitpid(-1, NULL, WNOHANG);
while (t > 0) {
fprintf(stdout, "SIGCHLD is sent from CHILD: %d\n", t);
/* Using -1 as the first argument so that we wait on all dead child processes.
* And we don't miss other SIGCHLD which were sent nearly at the same time.
* To see this, just count the number of "Complete." in the output.
*/
t = waitpid(-1, NULL, WNOHANG);
}
printf("Complete.\n");
}
int main (int argc, char *argv[])
{
struct sigaction act;
int i;
memset (&act, 0, sizeof(act));
act.sa_sigaction = &sigchld_hdl_action;
/* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */
/* The SA_NODEFER flag does not prevent the signal from being received from within its own signal
handler.
*/
act.sa_flags = SA_SIGINFO | SA_NODEFER | SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &act, 0)) {
perror ("sigaction");
return 1;
}
printf("PARENT: Here's my PID: %d\n", getpid());
/* Make some children. */
for (i = 0; i < 5; i++) {
pid_t forked_pid = fork();
switch (forked_pid) {
case -1:
perror ("fork");
return 1;
case 0:
printf("CHILD: Here's my PID: %d\n", getpid());
exit(0);
default:
printf("PARENT: Just created a child: %d\n", forked_pid);
}
}
while (1) {
printf("Sleeping Zzzzzz\n");
sleep(5);
}
return 0;
}
#include<stdio.h>;
#include <unistd.h>;
#include<stdlib.h>;
int main() {
char* host = (char*) malloc(sizeof(char)*100);
printf("%s\n", getenv("PATH"));
printf("%s\n", getenv("HOME"));
gethostname(host,100);
printf("%s\n", host);
char* dir = "newdir";
mkdir(dir);
}
#include <sys/wait.h>
# include <stdio.h>
# include <unistd.h>
#include<stdlib.h>
int main(void)
{
close(1);
printf("hi");
}
#include <sys/wait.h>
# include <stdio.h>
# include <unistd.h>
#include<stdlib.h>
int main(void)
{
char *const parmList[] = {"ls", "-l", NULL};
pid_t pid = fork();
if (pid == 0) {
if (execvp("ls", parmList) < 0){
perror("Error on execv.");
}
}
else {
while(pid != wait(0));
return 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment