Skip to content

Lab3 - Process

Print
  1. Download VM: https://drive.google.com/file/d/1orBRMplTzVuRwuaUqhlXepndEIQiaEaJ/view?usp=sharing
  2. Import VM: Import VM
  3. Select OVA File: OVA File
  4. กด Finish: Finish OVA File
  5. รอ Import: Wait import
  1. Start VM: Start VM
  2. Open browser พิมพ์ http://localhost:8080 CODE SERVER
  3. ตอน shutdown VM ใช้คำสั่ง poweroff

สร้างไฟล์ใน VSCode แล้วลง Extension

Example 1: Create a CSV file with your current running processes:

Section titled “Example 1: Create a CSV file with your current running processes:”
  • Install csvkit
Terminal window
pip3 install csvkit
  • Create csv file from ps
Terminal window
ps aux | head -10 | tr -s ' ' | cut -d' ' -f1,2,3,4,11 > processes.csv
# Add header manually or use:
echo "user,pid,cpu,mem,command" > processes_with_header.csv
ps aux | tail -n +2 | head -9 | tr -s ' ' | cut -d' ' -f1,2,3,4,11 >> processes_with_header.csv
csvlook processes_with_header.csv

Memory Layout

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h> // for malloc_usable_size (GNU extension)
int global_var = 100; // Global variable
static int static_global_var = 200; // Static global variable
void show_memory_layout() {
int stack_var = 300; // Local (stack) variable
static int static_local_var = 400; // Static local variable
int *heap_var = malloc(50 * sizeof(int)); // Heap allocation
// Write something to heap to prevent compiler optimization
for (int i = 0; i < 50; i++) heap_var[i] = i;
printf("\n=== MEMORY LAYOUT ===\n");
// Code address
printf("Code (function): %p\n", (void *)show_memory_layout);
// Global / static
printf("Global var: %p (size: %zu bytes)\n",
(void *)&global_var, sizeof(global_var));
printf("Static global var: %p (size: %zu bytes)\n",
(void *)&static_global_var, sizeof(static_global_var));
// Heap
printf("Heap var (malloc): %p (requested: %zu bytes, actual: %zu bytes)\n",
(void *)heap_var, 50 * sizeof(int), malloc_usable_size(heap_var));
// Stack
printf("Stack var (local): %p (size: %zu bytes)\n",
(void *)&stack_var, sizeof(stack_var));
printf("Static local var: %p (size: %zu bytes)\n",
(void *)&static_local_var, sizeof(static_local_var));
printf("======================\n");
free(heap_var); // Clean up
}
int main() {
show_memory_layout();
return 0;
}

OUTPUT

Terminal window
c@c:~/cos3105$ ./memory_layout
=== MEMORY LAYOUT ===
Code (function): 0x5cb6d9cbe1e9
Global var: 0x5cb6d9cc1010 (size: 4 bytes)
Static global var: 0x5cb6d9cc1014 (size: 4 bytes)
Heap var (malloc): 0x5cb718c1f2a0 (requested: 200 bytes, actual: 200 bytes)
Stack var (local): 0x7ffdb5b83568 (size: 4 bytes)
Static local var: 0x5cb6d9cc1018 (size: 4 bytes)
======================

create_process.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t p;
p=fork();
if(p==0) //child
{
printf("I am child having PID %d\n",getpid());
printf("My parent PID is %d\n",getppid());
}
else //parent
{
printf("I am parent having PID %d\n",getpid());
printf("My child PID is %d\n",p);
}
}

OUTPUT

Terminal window
I am parent having PID 9445
My child PID is 9446
I am child having PID 9446
My parent PID is 1835

create_orphan_process.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t p;
p=fork();
if(p==0)
{
sleep(5); //child goes to sleep and in the mean time parent terminates
printf("I am child having PID %d\n",getpid());
printf("My parent PID is %d\n",getppid());
}
else
{
printf("I am parent having PID %d\n",getpid());
printf("My child PID is %d\n",p);
}
}

OUTPUT

create_zombie_process.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t t;
t=fork();
if(t==0)
{
printf("Child having id %d\n",getpid());
}
else
{
printf("Parent having id %d\n",getpid());
sleep(15); // Parent sleeps. Run the ps command during this time
}
}

OUTPUT

Process : Prevent Zombie process by wait()

Section titled “Process : Prevent Zombie process by wait()”

prevent_zombie_process.c
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/wait.h>
int main()
{
pid_t p;
printf("before fork\n");
p=fork();
if(p==0)//child
{
printf("I am child having id %d\n",getpid());
printf("My parent's id is %d\n",getppid());
}
else//parent
{
wait(NULL);
printf("My child's id is %d\n",p);
printf("I am parent having id %d\n",getpid());
}
printf("Common\n");
}

OUTPUT

Prevent Zombie Process

write_shared_memory.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/shm.h>
#include<string.h>
int main()
{
int i;
void *shared_memory;
char buff[100];
int shmid;
/* creates shared memory segment with key 2345, having size 1024 bytes.
IPC_CREAT is used to create the shared segment if it does not exist.
0666 are the permisions on the shared segment */
shmid=shmget((key_t)2345, 1024, 0666|IPC_CREAT);
printf("Key of shared memory is %d\n",shmid);
//process attached to shared memory segment
shared_memory=shmat(shmid,NULL,0);
//this prints the address where the segment is attached with this process
printf("Process attached at %p\n",shared_memory);
printf("Enter some data to write to shared memory\n");
//get some input from user
read(0,buff,100);
//data written to shared memory
strcpy(shared_memory,buff);
printf("You wrote : %s\n",(char *)shared_memory);
}

OUTPUT

Write Shared Memory

read_shared_memory.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
int main()
{
int i;
void *shared_memory;
char buff[100];
int shmid;
shmid=shmget((key_t)2345, 1024, 0666);
printf("Key of shared memory is %d\n",shmid);
shared_memory=shmat(shmid,NULL,0); //process attached to shared memory segment
printf("Process attached at %p\n",shared_memory);
printf("Data read from shared memory is : %s\n",(char *)shared_memory);
}

OUTPUT

Read Shared Memory

send_queue.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define MAX_TEXT 512 //maximum length of the message that can be sent allowed
struct my_msg{
long int msg_type;
char some_text[MAX_TEXT];
};
int main()
{
int running=1;
int msgid;
struct my_msg some_data;
char buffer[50]; //array to store user input
msgid=msgget((key_t)14534,0666|IPC_CREAT);
if (msgid == -1) // -1 means the message queue is not created
{
printf("Error in creating queue\n");
exit(0);
}
while(running)
{
printf("Enter some text:\n");
fgets(buffer,50,stdin);
some_data.msg_type=1;
strcpy(some_data.some_text,buffer);
if(msgsnd(msgid,(void *)&some_data, MAX_TEXT,0)==-1) // msgsnd returns -1 if the message is not sent
{
printf("Msg not sent\n");
}
if(strncmp(buffer,"end",3)==0)
{
running=0;
}
}
}

OUTPUT

Send Message Queue

read_queue.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
struct my_msg{
long int msg_type;
char some_text[BUFSIZ];
};
int main()
{
int running=1;
int msgid;
struct my_msg some_data;
long int msg_to_rec=0;
msgid=msgget((key_t)14534,0666|IPC_CREAT);
while(running)
{
msgrcv(msgid,(void *)&some_data,BUFSIZ,msg_to_rec,0);
printf("Data received: %s\n",some_data.some_text);
if(strncmp(some_data.some_text,"end",3)==0)
{
running=0;
}
}
msgctl(msgid,IPC_RMID,0);
}

OUTPUT

Read Message Queue

producer.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
const int SIZE = 4096;
const char *name = "OS";
const char *message_0 = "Hello";
const char *message_1 = "World!";
int fd;
char *ptr;
fd = shm_open(name, O_CREAT|O_RDWR,0666);
ftruncate(fd, SIZE);
ptr = (char*)mmap(0, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
sprintf(ptr, "%s", message_0);
ptr += strlen(message_0);
sprintf(ptr, "%s", message_1);
ptr += strlen(message_1);
getchar();
return 0;
}
consumer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
const int SIZE = 4096;
const char *name = "OS";
int fd;
char *ptr;
fd = shm_open(name, O_RDWR,0666);
ptr = (char*)mmap(0, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
printf("%s\n", (char *)ptr);
shm_unlink(name);
return 0;
}

OUTPUT

Terminal window
HelloWorld!

What is a socket file?

A Unix domain socket is a special file used for local IPC between processes on the same system. Unlike network sockets (IP-based), these are file-based and live in the file system.

How to find them?

Terminal window
find /var/run /tmp -type s

OUTPUT

Terminal window
srw-rw---- 1 root docker 0 Jul 31 10:00 /var/run/docker.sock