Last active
November 20, 2016 17:01
-
-
Save moonblade/f3d86960bf2e8a48b46f08e4bdeddead to your computer and use it in GitHub Desktop.
osLab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
/*Socket obviously required*/ | |
#include <sys/socket.h> | |
/*Any shit ending with _t is prolly from this library*/ | |
#include <sys/types.h> | |
#include <string> | |
#include "string.h" | |
#include "unistd.h" | |
#include "netinet/in.h" | |
#define defPort 142536 | |
#define defPortDgram 253614 | |
#define max 256 | |
using namespace std; | |
/*Some random class to send and receive as a class instead of as simple character stream*/ | |
class mail | |
{ | |
public: | |
char *to,*from,*message; | |
mail(char* a,char* b,char* c): from(a),to(b),message(c){}; | |
void print() | |
{ | |
cout<<endl; | |
cout<<"from :"<<from<<endl; | |
cout<<"to :"<<to<<endl; | |
cout<<"message :"<<message<<endl; | |
cout<<endl; | |
} | |
}; | |
// To exit out of program on error, should be pretty easy to understand | |
void exitError(string error) | |
{ | |
cout<<error<<endl; | |
exit(-1); | |
} | |
/*To use as parent class for stuff that uses datagram socket*/ | |
class datagramSocketEndPoint | |
{ | |
protected: | |
/*Dsock is the socket descriptor*/ | |
int dsock; | |
/*Buffer is made void * so that it can even point to random class objects if needed*/ | |
void *buf; | |
sockaddr_storage returnAddress; | |
public: | |
datagramSocketEndPoint() | |
{ | |
/*Initialise a datagramsocket*/ | |
buf = new char[max]; | |
dsock = socket(AF_INET,SOCK_DGRAM,0); | |
if (dsock<0) | |
exitError("cannot create datagramSocket"); | |
} | |
/*Send data*/ | |
void sendd(void *data,int size,sockaddr *destinationAddress) | |
{ | |
/*man pages are your friend*/ | |
sendto(dsock,data,size,0,destinationAddress,sizeof(sockaddr_in)); | |
} | |
/*receive a buffer from sockfd*/ | |
void received(int type) | |
{ | |
socklen_t dummy = sizeof(sockaddr_in); | |
switch(type) | |
{ | |
/*Receive normal character stream*/ | |
case 0: | |
/*Since buffer is void*, cast is used to convert to character*/ | |
recvfrom(dsock,buf,max,0,(sockaddr *)&returnAddress,&dummy); | |
cout<<(char *)buf; | |
break; | |
} | |
} | |
}; | |
/*Superclass for classes that use streamsockets*/ | |
class streamSocketEndPoint | |
{ | |
protected: | |
/*buffer is used to send data, and sockfd is socket descriptor*/ | |
int sockfd; | |
void *buf; | |
public: | |
/*initialise buffer and socket descriptor*/ | |
streamSocketEndPoint() | |
{ | |
buf = new char[max]; | |
/*man socket (or man 2 socket in some systems to know what each are)*/ | |
sockfd=socket(AF_INET,SOCK_STREAM,0); | |
if (sockfd<0) | |
exitError("cannot create socket"); | |
} | |
/*Send data*/ | |
void send(void *data,int size) | |
{ | |
write(sockfd,data,size); | |
} | |
/*receive a buffer from sockfd*/ | |
void receive(int type=0) | |
{ | |
switch(type) | |
{ | |
/*Receive normal character stream*/ | |
case 0: | |
/*Since buffer is void*, cast is used to convert to character*/ | |
read(sockfd,buf,max); | |
cout<<(char *)buf; | |
break; | |
/*Receive a class object*/ | |
case 1: | |
read(sockfd,buf,sizeof(mail)); | |
((mail *)buf)->print(); | |
break; | |
} | |
} | |
~streamSocketEndPoint() | |
{ | |
close(sockfd); | |
} | |
}; | |
/*Sender class is the server | |
server will bind the address, listen to it, and when accepting a | |
connection will create a new client socket so that the listening socket is not interupted | |
*/ | |
class sender : public streamSocketEndPoint, public datagramSocketEndPoint | |
{ | |
public: | |
/*bind and listen, accept*/ | |
sockaddr_in mybind(int port,int &socket) | |
{ | |
/*Create a sockaddr_in type, with the same family and given port*/ | |
struct sockaddr_in saddr; | |
saddr.sin_family = AF_INET; | |
saddr.sin_port = htons(port); | |
saddr.sin_addr.s_addr=htonl(INADDR_ANY); | |
/*try and bind the sockfd to it*/ | |
if(bind(socket,(sockaddr *)&saddr,sizeof(saddr))<0) | |
exitError("Cannot bind socket"); | |
return saddr; | |
} | |
void bnla(int port) | |
{ | |
sockaddr_in saddr=mybind(port,sockfd); | |
/*Listen for incoming connection (only 1 parallel connection given)*/ | |
listen(sockfd,1); | |
/*dummy, not required later*/ | |
socklen_t dummy = sizeof(sockaddr_in); | |
/*overwriting socket for client via accept | |
REALLY REALLY BAD, DONT DO LIKE THIS, MAKE A NEW SOCKET | |
man 2 accept for details | |
*/ | |
sockfd = accept(sockfd,(sockaddr *)&saddr,&dummy); | |
} | |
void bnlad(int port) | |
{ | |
sockaddr_in saddr=mybind(port,dsock); | |
} | |
sockaddr* getClientAddress(int port) | |
{ | |
return (sockaddr *) &areturnAddress; | |
} | |
}; | |
/*Receiver class or client class will connect to server and send data*/ | |
class receiver : public streamSocketEndPoint, public datagramSocketEndPoint | |
{ | |
public: | |
/*Try and connect to server port*/ | |
void con(int port) | |
{ | |
/*sock addr data type, add port and family, connect*/ | |
sockaddr_in saddr; | |
saddr.sin_family = AF_INET; | |
saddr.sin_port = htons(port); | |
saddr.sin_addr.s_addr=htonl(INADDR_ANY); | |
if(connect(sockfd,(sockaddr *)&saddr,(socklen_t)sizeof(saddr))<0) | |
exitError("cannot connect"); | |
} | |
sockaddr_in getServerAddress(int port) | |
{ | |
/*sock addr data type, add port and family*/ | |
sockaddr_in saddr; | |
saddr.sin_family = AF_INET; | |
saddr.sin_port = htons(port); | |
saddr.sin_addr.s_addr=htonl(INADDR_ANY); | |
return saddr; | |
} | |
}; | |
/*driver program for above*/ | |
int main(int argc, char const *argv[]) | |
{ | |
char opt='s'; | |
if(rand()%5==0) | |
{ | |
cout<<"Server or Client (s/C)?: "; | |
cin>>opt; | |
if(opt!='s') | |
{ | |
/*Init receiver*/ | |
receiver r; | |
/*Connect to port*/ | |
r.con(defPort); | |
/*Single one send*/ | |
char a[20]="data from client"; | |
r.send(a,strlen(a)); | |
/*Single one receive*/ | |
r.receive(); | |
/*Send object instead of char stream*/ | |
mail *m = new mail("[email protected]","[email protected]","message is message"); | |
r.send(m,sizeof(mail)); | |
} | |
else | |
{ | |
/*init sender*/ | |
sender s; | |
/*bind, listen accept from port*/ | |
s.bnla(defPort); | |
/*Single one receive*/ | |
s.receive(); | |
// Single one send | |
char a[20]="data from server"; | |
s.send(a,strlen(a)); | |
/*Receive mail (type 1 message)*/ | |
s.receive(1); | |
} | |
} | |
else | |
{ | |
cout<<"Server or Client (s/C)?: "; | |
cin>>opt; | |
if(opt!='s') | |
{ | |
/*STREAM SOCKET*/ | |
/*Init receiver*/ | |
receiver r; | |
/*DATAGRAM SOCKET*/ | |
sockaddr_in server = r.getServerAddress(defPortDgram); | |
char a[20]="data from client"; | |
r.sendd(a,strlen(a),(sockaddr*) &server); | |
r.received(0); | |
} | |
else | |
{ | |
/*init sender*/ | |
sender s; | |
/*DATAGRAM SOCKET*/ | |
s.bnlad(defPortDgram); | |
s.received(0); | |
sockaddr *client = s.getClientAddress(defPortDgram); | |
char a[20]="data from server"; | |
s.sendd(a,strlen(a),client); | |
} | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Iostream for obvious reasons | |
#include<iostream> | |
// Has important types stuff thats used throughout the programs, say pid_t, or size_t etc etc | |
#include<sys/types.h> | |
// For getting POSIX (unix like) functions, you know like pipe, fork, essentially system call features | |
#include<unistd.h> | |
// String stuff | |
#include<string.h> | |
// Math stuff | |
#include<math.h> | |
using namespace std; | |
/*Whenever a forked process calls the print function, it passes the fork number to it, to avoid confusion. | |
The print function prints the details of the current fork*/ | |
void print(int control) | |
{ | |
/*The process number or fork number*/ | |
string name="process "+to_string(control); | |
/*Process Id, id of process that will be shown in ps ax command in linux*/ | |
cout<<name<<" pid "<<getpid()<<endl; | |
/*Parent Process Id, Id of process that spawned the current process, for the initial process, parent id is 0*/ | |
cout<<name<<" ppid "<<getppid()<<endl; | |
/*User and group id of the user that is running the current process (your login and which group your login belongs to)*/ | |
cout<<name<<" uid "<<getuid()<<endl; | |
cout<<name<<" egid "<<getegid()<<endl; | |
cout<<endl; | |
} | |
int main() | |
{ | |
pid_t pid,pid2,pid3,par = getpid(); | |
int mul=0; | |
/*Fork() makes two process, one the original process fork returns the parent process id | |
if pid==0, child process, else parent process (depends on machine, may invert in some machines) | |
1---+ | |
| | | |
2 3 | |
| | |
4 | |
can be done by | |
fork (gets 1 and 2) | |
if parent(ie 1) | |
fork again (1 and 3) | |
if child (3) | |
fork again (3 and 4) | |
so any tree structure can be made | |
The tree is confirmed using parent pids | |
*/ | |
pid = fork(); | |
if(pid) | |
{ | |
// Parent process | |
pid2=fork(); | |
if(pid2) | |
print(1); | |
else | |
{ | |
pid3=fork(); | |
if(pid3) | |
print(2); | |
else | |
print(3); | |
} | |
} | |
else | |
{ | |
print(4); | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*Create a program that prints a and b such that there are no three a's or three b's at the same time*/ | |
/*It can also be viewed as a Producer consumer problem with max size 2*/ | |
#include<iostream> | |
/*For semaphore shit*/ | |
#include<semaphore.h> | |
#include<pthread.h> | |
#include<fcntl.h> | |
#include<stdio.h> | |
using namespace std; | |
/*Make two semaphores a and b, since the maximum occurance together is 2, | |
init one of them with 2 and other with 0 (2,0 or 1,1 or 0,2) | |
when one is over, signal the other | |
wait a | |
do shit for a | |
signal b | |
will be the code | |
*/ | |
sem_t *sema,*semb; | |
/*a will wait for itself, but signal the other one*/ | |
void *workera(void *args) | |
{ | |
/*Infinite loop, wait a, do a, signal b*/ | |
while(1) | |
{ | |
sem_wait(sema); | |
cout<<"a"; | |
sem_post(semb); | |
} | |
} | |
void *workerb(void *args) | |
{ | |
/*Infinite loop, wait b, do b, signal a*/ | |
/*Thus the maximum sema or semb can get is 2, hence at most 2 a or 2 b occur together*/ | |
while(1) | |
{ | |
sem_wait(semb); | |
cout<<"b"; | |
sem_post(sema); | |
} | |
} | |
int main() | |
{ | |
/*Initialise semaphores after allocating memory*/ | |
sema = (sem_t*) malloc(sizeof(sem_t)); | |
semb = (sem_t*) malloc(sizeof(sem_t)); | |
/*Sucks to be you, can't init shit*/ | |
pthread_t a,b; | |
if(sem_init(sema,0,1)==-1) | |
{ | |
cout<<"Error"; | |
} | |
else | |
{ | |
if(sem_init(semb,0,1)==-1) | |
{ | |
cout<<"Error"; | |
} | |
else | |
{ | |
/*Start your enignes*/ | |
pthread_create(&a,NULL,&workera,NULL); | |
/*Go go go*/ | |
pthread_create(&b,NULL,&workerb,NULL); | |
/*Wont stop ever so pointless*/ | |
pthread_exit(NULL); | |
} | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#define max 30 | |
#define ws 8 | |
using namespace std; | |
/* | |
Sliding window class is used to simulate a window where the acknowledgements to be received at the sender side are kept | |
Sliding window operations are | |
Add acknowledgement packet: | |
Add a packet with a certain acknowledgement number onto the window | |
Acknowledge packet: | |
When a packet is ackowledged, it is deleted from the sliding window | |
slide window: | |
|0|0|3|0|5|6|0| | |
^ | |
| | |
first non acknowledged packet is here, so sliding window can be slid two spaces to give | |
|3|0|5|6|0|0|0| | |
Thus making space for new packets at the end | |
find first non acknowledged packet: | |
the done() function finds the packet yet to be acknowledged and sends its index(in sliding window) and the actual acknowledgement number as a pair | |
if all packets are acknowledged, it returns 0, ie window can be slid entirely | |
resend(): | |
in selective repeat only frames that are not acknowledged are resent again, so a resend funciton checks if given acknowledge frame is empty or not | |
|0|0|0|4| | |
resend(1) => false | |
resend(4) => true | |
*/ | |
class slidingWindow | |
{ | |
public: | |
int *q; | |
int shift; | |
int size; | |
slidingWindow(int size) | |
{ | |
this->size=size; | |
q=new int[size]; | |
} | |
slidingWindow() | |
{ | |
this->size=ws; | |
q=new int[size]; | |
shift=0; | |
for(int i=0;i<size;++i) | |
q[i]=0; | |
} | |
void add(int a) | |
{ | |
q[(a-shift)%size]=a; | |
} | |
void ack(int a) | |
{ | |
q[(a-shift)%size]=0; | |
} | |
void shif(int s) | |
{ | |
shift+=s; | |
} | |
/*The index of the first acknowledge number not acknowledged(in the window)+1, and the acknowledge number*/ | |
/*0 is reserved for all acknowledged*/ | |
pair<int,int> done() | |
{ | |
for(int i=0;i<size;++i) | |
{ | |
if(q[i]!=0) | |
return *new pair<int,int>(i+1,q[i]); | |
} | |
return *new pair<int, int>(0,0); | |
} | |
bool resend(int a) | |
{ | |
return q[(a-shift)%size]!=0; | |
} | |
}; | |
/* | |
Receiver is a simple class used only as a medium to receive data and randomly decide on either sending or not sending ack | |
Both data and its index (which is the ack) is sent, it randomly either sends ack back or sends -1 (NACK - negative acknowledgement) | |
*/ | |
class receiver | |
{ | |
public: | |
int receive(int a,int ack) | |
{ | |
cout<<"Receiver : "<<"Received value "<<a<<" with ack "<<ack<<endl; | |
if(rand()%3) | |
{ | |
cout<<"Receiver : "<<"Sending acknowledge : "<<ack<<endl; | |
return ack; | |
} | |
else | |
{ | |
cout<<"Receiver : "<<"Sending no acknowledge"<<endl; | |
return -1; | |
} | |
} | |
}; | |
/* | |
In its constructor sender initialises an array called data which is the data to be sent to receiver | |
Stop and Wait | |
------------- | |
Stop and wait and go back n are essentially the same with the difference that stop and wait has window size 1 | |
Each packet waits for its acknowledgement, if ack received, next packet is sent, else the same packet is resent, | |
Go back N | |
--------- | |
A window of size t is kept | |
t packets are sent simultaneously | |
1|2|3|4|5|6|7|8 <-- sliding window | |
The packets that are acknowledged are eliminated | |
0|0|3|0|0|6|0|8 <-- sliding window after ack | |
The sliding window is slid till the first non acknowledged packet | |
|3|0|0|6|0|8|0|0 <-- new sliding window | |
all the elements in the sliding window are sent again | |
|3|4|5|6|7|8|9|10 <-- new sliding window | |
Selective repeat | |
---------------- | |
A window of size t is kept | |
t packets are sent simultaneously | |
1|2|3|4|5|6|7|8 <-- sliding window | |
The packets that are acknowledged are eliminated | |
0|0|3|0|0|6|0|8 <-- sliding window after ack | |
The Ones that are non acknowledged are sent again till ack is reached | |
0|0|0|0|0|0|0|8 <-- sliding window after ack (8 still did not get ack resend 8) | |
0|0|0|0|0|0|0|0 <-- sliding window after ack final | |
entire sliding window is shifted | |
|0|0|0|0|0|0|0|0 <-- sliding window after ack final | |
*/ | |
class sender | |
{ | |
public: | |
int data[max]; | |
/*Data init as multiples of 5*/ | |
sender() | |
{ | |
for(int i=0;i<max;++i) | |
{ | |
data[i]=(i+1)*5; | |
} | |
} | |
/*Selective repeat ARQ*/ | |
void selectiveRepeat(receiver r) | |
{ | |
cout<<"Simulation of Selective Repeat sliding window protocol"<<endl; | |
cout<<"------------------------------------------------------"<<endl; | |
/*Sent is the index till which sending has been done | |
When sent==max, completed*/ | |
int sent=0; | |
/*Create a sliding window os size WINDOWSIZE (ws)*/ | |
slidingWindow s; | |
/*This boolean flag is used to check if entire window is slid and next 8 data can be sent simultaneously, since at the beginnig there is no ack to be received next 8 data can be sent, and this bool is set to true*/ | |
bool next=true; | |
while(sent<max) | |
{ | |
/*Whether or not entire window is to be slid, if there is a non ack member, this is made false*/ | |
bool slide=true; | |
if(next)//ie send the next data | |
{ | |
/*Sent one window size amount of data and acknowledge(remove from window) the ones that were acknowledged*/ | |
next=false; | |
for(int j=0;j<ws && j+sent<max;++j) | |
{ | |
s.add(sent+j); | |
cout<<"Sender : "<<"Sent data : "<<data[sent+j]<<endl; | |
int ack=r.receive(data[sent+j],sent+j); | |
if(ack!=-1) | |
{ | |
s.ack(ack); | |
} | |
} | |
} | |
/*For the ones in sliding window*/ | |
for(int j=0;j<ws && j+sent<max;++j) | |
{ | |
/*If no acknowledge was received, ie it has to be resent?*/ | |
if(s.resend(j+sent)) | |
{ | |
/*Resend the single data frame and check if ack came again*/ | |
slide=false; | |
cout<<"Sender : "<<"Resending data : "<<data[sent+j]<<endl; | |
int ack=r.receive(data[sent+j],sent+j); | |
if(ack!=-1) | |
{ | |
s.ack(ack); | |
} | |
} | |
} | |
auto k = s.done(); | |
if(k.first==0) | |
{ | |
/*If all the frames in the window are acknowledged slide the entire window, In selective repeat, only entire sliding has been done*/ | |
if(slide) | |
{ | |
cout<<"Sender : "<<"Sliding entire window"<<endl; | |
s.shif(s.size); | |
sent+=s.size; | |
next=true; | |
} | |
} | |
/*If at least one is not acknowledged, same window is kept and data is resend till ack is received and window is completely acknowledged*/ | |
} | |
} | |
/*Go back N ARQ*/ | |
void goBackN(receiver r) | |
{ | |
cout<<"Simulation of go back N sliding window protocol"<<endl; | |
cout<<"-----------------------------------------------"<<endl; | |
int sent=0; | |
/*None sent yet, sliding window of size ws*/ | |
slidingWindow s; | |
while(sent<max) | |
{ | |
/*Send ws amount of data together and acknowledge the ones that get ack back*/ | |
for(int j=0;j<ws && j+sent<max;++j) | |
{ | |
s.add(sent+j); | |
cout<<"Sender : "<<"Sent data : "<<data[sent+j]<<endl; | |
int ack=r.receive(data[sent+j],sent+j); | |
if(ack!=-1) | |
{ | |
s.ack(ack); | |
} | |
} | |
/*Find the first non acknowledged frame*/ | |
auto k = s.done(); | |
/*If the first non acknowledged frame is not the first frame, then window can be shifted be that amount* | |
|0|0|3|4|5|6|0| <- shift by two to get | |
|3|4|5|6|0|0|0| <- shift by two to get | |
*/ | |
if(k.first>1) | |
{ | |
cout<<"Sender : "<<"Sliding window by "<<k.first-1<<endl; | |
s.shif(k.first-1); | |
sent+=k.first-1; | |
} | |
/*If the first frame is not ack, can't shift, do nothing | |
|1|0|3|4|5|6|0| <- No shift */ | |
else if(k.first==1) | |
{ | |
cout<<"Sender : "<<"Resending"<<endl; | |
} | |
/*Everything ack, shift entire window | |
|0|0|0|0|0|0|0| <- full shift | |
|0|0|0|0|0|0|0| <- final result | |
*/ | |
else if(k.first==0) | |
{ | |
cout<<"Sender : "<<"Sliding entire window"<<endl; | |
s.shif(s.size); | |
sent+=s.size; | |
} | |
} | |
} | |
void sendStopAndWait(receiver r) | |
{ | |
/*Go back N with sliding window size as 1*/ | |
cout<<"Simulation of stop and wait sliding window protocol"<<endl; | |
cout<<"---------------------------------------------------"<<endl; | |
int sent=0; | |
/*only one element in window*/ | |
slidingWindow s(1); | |
while(sent<max) | |
{ | |
/*Send one, wait for ack, ack if received*/ | |
s.add(sent); | |
cout<<"Sender : "<<"Sent data : "<<data[sent]<<endl; | |
int ack=r.receive(data[sent],sent); | |
if(ack==-1) | |
{ | |
cout<<"Sender : "<<"No ack Received, resending"<<endl; | |
} | |
else | |
{ | |
s.ack(ack); | |
} | |
auto k = s.done(); | |
/*This wont execute since k.first = 0 or 1*/ | |
if(k.first>1) | |
{ | |
cout<<"Sender : "<<"Sliding window by "<<k.first<<endl; | |
s.shif(k.first); | |
sent+=k.first; | |
} | |
/*No ack*/ | |
else if(k.first==1) | |
{ | |
cout<<"Sender : "<<"Resending"<<endl; | |
} | |
/*Ack got, shift by one | |
|0| init | |
|0| final | |
*/ | |
else if(k.first==0) | |
{ | |
cout<<"Sender : "<<"Sliding entire window"<<endl; | |
s.shif(s.size); | |
sent+=s.size; | |
} | |
} | |
} | |
}; | |
int main(int argc, char const *argv[]) | |
{ | |
sender s; | |
receiver r; | |
s.sendStopAndWait(r); | |
s.goBackN(r); | |
s.selectiveRepeat(r); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*Same as socket program, but instead fill the buffer with parts of file and regurgitate into a file at the other side*/ | |
//Converted both server and client into a single program, so use as ./12 s filename or ./12 c filename | |
#include<iostream> | |
#include<stdio.h> | |
#include<sys/types.h> | |
#include<string.h> | |
#include<stdlib.h> | |
#include<sys/socket.h> | |
#include<arpa/inet.h> | |
#include<unistd.h> | |
#include<fstream> | |
#define sa struct sockaddr | |
#define listenq 5 | |
#define defport "132445" | |
using namespace std; | |
class receiver | |
{ | |
public: | |
char* filename; | |
char* port; | |
receiver(char* filename, char* port) | |
{ | |
this->filename = filename; | |
this->port = port; | |
} | |
void receive() | |
{ | |
int fd,sockfd,listenfd,connfd; | |
pid_t childpid; | |
socklen_t client; | |
struct sockaddr_in servaddr, cliaddr; | |
listenfd = socket(AF_INET, SOCK_STREAM, 0); | |
bzero(&servaddr, sizeof(servaddr)); | |
servaddr.sin_family = AF_INET; | |
servaddr.sin_addr.s_addr=htonl(INADDR_ANY); | |
servaddr.sin_port = htons(atoi(this->port)); | |
bind(listenfd,(sa*)&servaddr,sizeof(servaddr)); | |
listen(listenfd,listenq); | |
client=sizeof(cliaddr); | |
connfd=accept(listenfd,(sa*)&cliaddr,&client); | |
char buffer[100]; | |
bzero(buffer,sizeof(buffer)); | |
ofstream f(filename); | |
buffer[0]='r'; | |
while(buffer[0]!='\0') | |
{ | |
read(connfd,buffer,100); | |
f<<buffer; | |
f<<'\n'; | |
} | |
f.close(); | |
printf("the file received"); | |
} | |
}; | |
class sender | |
{ | |
public: | |
char *filename; | |
char *port; | |
sender(char *filename, char *port) | |
{ | |
this->filename = filename; | |
this->port = port; | |
} | |
void send() | |
{ | |
int sockfd; | |
char fname[25]; | |
int len; | |
struct sockaddr_in servaddr,cliaddr; | |
sockfd=socket(AF_INET,SOCK_STREAM,0); | |
bzero(&servaddr, sizeof(servaddr)); | |
servaddr.sin_family=AF_INET; | |
servaddr.sin_addr.s_addr=htonl(INADDR_ANY); | |
servaddr.sin_port=htons(atoi(this->port)); | |
inet_pton(AF_INET,this->port,&servaddr.sin_addr); | |
connect(sockfd,(sa*)&servaddr,sizeof(servaddr)); | |
char buffer[100]; | |
ifstream f(filename); | |
while(f.getline(buffer,sizeof(buffer))) | |
write(sockfd,buffer,100); | |
char end='\0'; | |
memcpy(buffer,&end,1); | |
write(sockfd,buffer,100); | |
f.close(); | |
cout<<"sent"<<endl; | |
} | |
}; | |
int main(int argc, char **argv) | |
{ | |
if(argc<3) | |
{ | |
cout<<"usage : netcat s/c filename [port]"<<endl; | |
} | |
//cout<<argv[1]; | |
if (argv[1][0]=='s') | |
{ | |
// cout<<"sender"; | |
char port[10] = defport; | |
if(argc>3) | |
strcpy(port,argv[3]); | |
// cout<<port; | |
sender s(argv[2],port); | |
s.send(); | |
} | |
else | |
{ | |
// cout<<"receiver"; | |
char port[10] = defport; | |
if(argc>3) | |
strcpy(port,argv[3]); | |
// cout<<port; | |
receiver r(argv[2],port); | |
r.receive(); | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Same as socket, use udp (so slight syntax changes) | |
//pass an object instead of random data | |
//server | |
#include <iostream> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <string.h> | |
#include <stdlib.h> | |
using namespace std; | |
struct mail{ | |
char from[255],to[255],subject[1024],content[1024]; | |
}; | |
int main(int argc,char **argv){ | |
int udpSocket, nBytes; | |
char buffer[255]; | |
struct sockaddr_in servaddr, cliaddr; | |
struct sockaddr_storage servsto; | |
socklen_t addr_size, cli_size; | |
int i; | |
udpSocket=socket(PF_INET,SOCK_DGRAM,0); | |
servaddr.sin_family=AF_INET; | |
servaddr.sin_port=htons(atoi(argv[1])); | |
servaddr.sin_addr.s_addr=htonl(INADDR_ANY); | |
memset(servaddr.sin_zero,'\0',sizeof(servaddr.sin_zero)); | |
bind(udpSocket,(struct sockaddr *)&servaddr,sizeof(servaddr)); | |
addr_size=sizeof(servsto); | |
struct mail m; | |
nBytes=recvfrom(udpSocket,&m,sizeof(m),0,(struct sockaddr *)&servsto,&addr_size); | |
cout<<"FROM :" <<m.from<<endl; | |
cout<<"TO: "<<m.to<<endl; | |
cout<<"SUBJECT: "<<m.subject<<endl; | |
cout<<"CONTENT: "<<m.content<<endl; | |
bzero(buffer,255); | |
strcpy(buffer,"recieved"); | |
sendto(udpSocket,buffer,9,0,(struct sockaddr *)&servsto,addr_size); | |
return 0; | |
} | |
//client | |
#include <iostream> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <string.h> | |
#include <stdlib.h> | |
using namespace std; | |
struct mail{ | |
char from[255],to[255],subject[1024],content[1024]; | |
}; | |
int main(int argc, char **argv){ | |
int cliSocket, portNum, nBytes; | |
char buffer[255]; | |
struct sockaddr_in servaddr; | |
socklen_t addr_size; | |
cliSocket=socket(PF_INET,SOCK_DGRAM,0); | |
servaddr.sin_family=AF_INET; | |
servaddr.sin_port=htons(atoi(argv[1])); | |
servaddr.sin_addr.s_addr=htonl(INADDR_ANY); | |
memset(servaddr.sin_zero,'\0',sizeof(servaddr.sin_zero)); | |
addr_size=sizeof(servaddr); | |
struct mail m; | |
cout<<"FROM: "; | |
cin.getline(m.from,255); | |
cout<<"TO: "; | |
cin.getline(m.to,255); | |
cout<<"SUBJECT: "; | |
cin.getline(m.subject,1024); | |
cout<<"content: "; | |
cin.getline(m.content,1024); | |
sendto(cliSocket,&m,sizeof(m),0,(struct sockaddr *)&servaddr,addr_size); | |
nBytes=recvfrom(cliSocket,buffer,255,0,NULL,NULL); | |
cout<<buffer; | |
return 0; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Pipe original program, send array and find primes in them, assuming you know normal pipes, instead of one data, first send size then send array then find primes in them on the receieving side | |
#include<sys/types.h> | |
#include<iostream> | |
#include<unistd.h> | |
#define max 10 | |
using namespace std; | |
/*check if n is prime */ | |
int isprime(int n) | |
{ | |
if(n<2) | |
return 0; | |
if(n==2) | |
return 1; | |
for(int i=2; i<=n/2; i++) | |
if(n%i==0) | |
return 0; | |
return 1; | |
} | |
//print inside a process, so process id and a number to print is given | |
void print(int p, int &n) | |
{ | |
cout<<p<<" says : "<<n<<"\n"; | |
} | |
// Print all primes in an array, also print pid | |
// combination of above two | |
void printprimes(int p,int a[],int s) | |
{ | |
for(int i=0;i<s;++i) | |
if(isprime(a[i])) | |
print(p,a[i]); | |
} | |
// function to exit | |
void er() | |
{ | |
cout<<" Pipe not created "; | |
exit(0); | |
} | |
// Read number in process p | |
void read(int p, int &n) | |
{ | |
cin>>n; | |
} | |
int main() | |
{ | |
// P is used for storing process number | |
int p; | |
// A two integer size array will be used as our pipe | |
int fd[2]; | |
// Here size of the data is passed | |
int size[2]; | |
// make pipe of both | |
if(pipe(fd)==-1) | |
{ | |
er(); | |
return 0; | |
} | |
if(pipe(size)==-1) | |
{ | |
er(); | |
return 0; | |
} | |
// make two processes | |
p=fork(); | |
if(p) | |
{ | |
//parent | |
// close first part | |
close(fd[0]); | |
close(size[0]); | |
// send size | |
cout<<"1 asks enter n : "; | |
int a[max],n; | |
cin>>n; | |
write(size[1],&n,sizeof(int)); | |
// send array | |
cout<<"1 asks enter elements : "; | |
for(int i=0;i<n;++i) | |
cin>>a[i]; | |
write(fd[1],a,n*sizeof(int)); | |
} | |
else | |
{ | |
//child | |
// close second half | |
close(fd[1]); | |
close(size[1]); | |
int b[max],c; | |
// get size | |
read(size[0],&c,sizeof(int)); | |
// get array | |
read(fd[0],b,c*sizeof(int)); | |
// print the primes | |
printprimes(2,b,c); | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Minimal program for pipes, send a number | |
#include<sys/types.h> | |
#include<iostream> | |
#include<unistd.h> | |
#define max 10 | |
using namespace std; | |
int main() | |
{ | |
// p is used to check if fork is parent or child | |
pid_t p; | |
// file descriptor of two integer length array, this will serve as the pipe between processes | |
// first process |x| | ---> | |x| second process | |
// first part of array of first process(i/p), and second part of array of second process(o/p) is not used | |
// first process disables the fd[0], and copies data to fd[1] | |
// second process disables fd[1] and reads data from fd[0] | |
int fd[2]; | |
// Make the fd into a pipe, if fail exit | |
if(pipe(fd)==-1) | |
{ | |
// no pipe | |
return 0; | |
} | |
// Fork to create two processes | |
p=fork(); | |
if(p) | |
{ | |
//parent | |
close(fd[0]); | |
int n=20; //data to transmit | |
// Write data to fd[1] of pipe (o/p part) | |
write(fd[1],&n,sizeof(int)); | |
// write(fd[1],array,sizeof(int)*arraysize); to write array | |
} | |
else | |
{ | |
//child | |
close(fd[1]); | |
int c; | |
// Read data from fd[0] of pipe (i/p part) | |
read(fd[0],&c,sizeof(int)); | |
// read(fd[0],array,sizeof(int)*arraysize); to read array | |
cout<<c; | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ipc using message queues | |
#include<iostream> | |
// For sleep command (might not be used in this) | |
#include<sys/wait.h> | |
// Posix shit | |
#include<unistd.h> | |
// Inter Process Communication, some shit like msgbuf maybe? | |
#include<sys/ipc.h> | |
// For message queue specific shit | |
#include<sys/msg.h> | |
#include<string> | |
#include<string.h> | |
#define max 20 | |
using namespace std; | |
// Messages have a specific structure, they should be a long (message type number) and a char array of | |
// the actual message | |
// The names msgbuff, mtype and mbuff can be any shit | |
struct msgbuff | |
{ | |
long mtype; | |
char mbuff[max]; | |
}; | |
// Print with process id and string | |
// glorified PA System, process 1 says : blah blah | |
void say(string a, string b) | |
{ | |
cout<<a<<" Says : "<<b; | |
} | |
int main() | |
{ | |
// This will be the message q id | |
int msgq; | |
// Message q id is generated with a preshared key, this key is given to every participant and the id | |
// is generated with this key with msgget() | |
key_t k=123; | |
// Flags, create if not exist and other permissions needed | |
int msgflag=IPC_CREAT|0666; | |
// Get the q id from the flag and key | |
msgq=msgget(k,msgflag); | |
//private only owner, EXCL exclusive only one guy gets, CREAT create if not exist flags are also available | |
pid_t p; | |
//fork the shit out of it | |
p=fork(); | |
if(!p) | |
{ | |
// Message queue is not blocking, the queue will get filled as you add more messages, and will | |
// clear as you collect, works like a stream in cpp | |
say("1","started\n"); | |
//Create a msg buffer | |
msgbuff a; | |
// read data into the message buffer, of message type 1 | |
msgrcv(msgq,&a,sizeof(a.mbuff),1,0); | |
// print it | |
say("1",a.mbuff); | |
say("1","ended\n"); | |
return 0; | |
} | |
else | |
{ | |
// sender | |
say("2","started\n"); | |
// message buffer | |
msgbuff a; | |
// of type 1 messages | |
a.mtype=1; | |
// add message | |
strcpy(a.mbuff,"Hello World\n"); | |
// send it | |
msgsnd(msgq,&a,sizeof(a.mbuff),0); | |
say("2","ended\n"); | |
} | |
return 0; | |
} | |
/*Addendum: Randomly goes haywire when cin is used instead of an automated loop as given, when a chat | |
application is made it randomly decides not to send any data and there has been no fix so far, some | |
found the same code to work perfectly on some machines*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<iostream> | |
#include<sys/types.h> | |
// needed shit | |
#include<sys/socket.h> | |
#include<netinet/in.h> | |
#include<netdb.h> | |
#include<unistd.h> | |
#include<string.h> | |
using namespace std; | |
int main(){ | |
int sockfd,newsockfd,portno,n; | |
socklen_t serv_len; | |
struct sockaddr_in servAddr; | |
char buffer[256]; | |
// make a socket | |
portno=20009; | |
sockfd=socket(AF_INET,SOCK_STREAM,0); | |
if(sockfd<0){ | |
cout<<"ErroropeningSocket!"; | |
return 0; | |
} | |
// need server address in servAddr | |
bzero( (char*)&servAddr , sizeof(servAddr) ); | |
servAddr.sin_family=AF_INET; | |
servAddr.sin_port=htons(portno); | |
// Try to connect to server | |
if( connect( sockfd, (struct sockaddr*)&servAddr ,sizeof(servAddr) ) <0 ) | |
cout<<"connecctionErrror"; | |
// Keep sending messages | |
while(1){ | |
cout<<"Enter the Message: "; | |
bzero(buffer,256); | |
cin>>buffer; | |
n=write(sockfd,buffer,strlen(buffer)); | |
if(n<0){ | |
cout<<"ErrorWritingToSocket"; | |
return 0; | |
} | |
bzero(buffer,256); | |
n=read(sockfd,buffer,255); | |
cout<<"message: "<<buffer<<endl; | |
} | |
close(sockfd); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<sys/types.h> | |
// For shit on sockets | |
#include<sys/socket.h> | |
#include<iostream> | |
// This | |
#include<netdb.h> | |
// And this are also required | |
#include<netinet/in.h> | |
#include<string.h> | |
#include<unistd.h> | |
using namespace std; | |
// Socket involves a lot of mugging up | |
int main(){ | |
// Socket discriptors to be used | |
int sockfd,newsockfd,portno,n; | |
// Socklength type for length of client storage | |
socklen_t clilen; | |
// buffer to haul data | |
char buffer[256]; | |
struct sockaddr_in servAddr,cliAddr; | |
// Create socket | |
sockfd=socket(AF_INET,SOCK_STREAM,0); | |
if(sockfd<0){ | |
cout<<"errorOpeningSocket"; | |
return 0; | |
} | |
bzero( (char*)&servAddr , sizeof(servAddr) ); | |
portno=20009; | |
// Add the server address and port servAddr | |
servAddr.sin_family=AF_INET; | |
servAddr.sin_port=htons(portno); | |
//bind to server address | |
if( bind( sockfd,(struct sockaddr*) &servAddr, sizeof(servAddr) ) <0 ){ | |
cout<<"ErrorOnbinding"; | |
return 0; | |
} | |
// Listen for incoming connections (5 at a time) | |
listen(sockfd,5); | |
// If connected create a new socket out of clientlength | |
clilen=sizeof(cliAddr); | |
newsockfd=accept( sockfd, (struct sockaddr*) &cliAddr, &clilen ); | |
if(newsockfd<0){ | |
cout<<"ErrorOnAccept!"; | |
return 0; | |
} | |
// Keep receiveing and sending messages | |
while(1){ | |
bzero(buffer,256); | |
n=read(newsockfd,buffer,255); | |
if(n<0){ | |
cout<<"ErrorReadingFromSocket!"; | |
return 0; | |
} | |
cout<<"Message: "<<buffer<<endl; | |
cin>>buffer; | |
n=write(newsockfd,buffer,strlen(buffer)); | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<stdio.h> | |
#include<iostream> | |
#include<unistd.h> | |
// For vfs shit | |
#include<sys/statvfs.h> | |
using namespace std; | |
int main() | |
{ | |
// A struct explained in pdf of osLab by vinod | |
struct statvfs data; | |
// Give valid path | |
char path[128]="/home/us/s13/s1338/s7/6-vfs"; | |
// get stats of file system | |
int ret=statvfs(path,&data); | |
if(ret==-1) | |
return -1; | |
// Print some shit from those stats | |
cout<<"free blocks : "<<data.f_blocks<<endl; | |
cout<<"b free : "<<data.f_bfree<<endl; | |
cout<<"free size : "<<data.f_frsize<<endl; | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <vector> | |
#include <algorithm> | |
#define max 20 | |
using namespace std; | |
void print(vector<int> a) | |
{ | |
auto i=a.begin(); | |
auto k=a.end(); | |
//cout<<"\n"; | |
for(;i!=k;++i) | |
{ | |
cout<<*i<<" "; | |
} | |
cout<<"\n"; | |
} | |
class matrix | |
{ | |
public: | |
int r; | |
int c; | |
int m[max][max]; | |
void read() | |
{ | |
//cout<<"dim : "; | |
cin>>r>>c; | |
for(int i=0;i<r;++i) | |
for(int j=0;j<c;++j) | |
cin>>m[i][j]; | |
} | |
matrix operator -(matrix b) | |
{ | |
matrix d; | |
d.r=r; | |
d.c=c; | |
for(int i=0;i<r;++i) | |
for(int j=0;j<c;++j) | |
d.m[i][j]=m[i][j]-b.m[i][j]; | |
return d; | |
} | |
void print() | |
{ | |
for(int i=0;i<r;++i) | |
{ | |
for(int j=0;j<c;++j) | |
cout<<m[i][j]<<" "; | |
cout<<"\n"; | |
} | |
} | |
int find(vector<int> row, vector<bool> finish) | |
{ | |
for(int i=0;i<r;++i) | |
{ | |
int f=1; | |
for(int j=0;j<c;++j) | |
{ | |
if(m[i][j]>row[j]) | |
f=0; | |
} | |
if(f && !finish[i]){ | |
cout<<i<<"th row : "; | |
::print(getRow(i)); | |
::print(row); | |
return i; | |
} | |
} | |
return -1; | |
} | |
void chrow(int row, vector<int> nrow) | |
{ | |
for(int j=0;j<c;++j) | |
m[row][j]=nrow[j]; | |
} | |
vector<int> getRow(int row) | |
{ | |
vector<int> a; | |
for(int j=0;j<c;++j) | |
a.push_back(m[row][j]); | |
return a; | |
} | |
}; | |
vector<int> minusv(vector<int> a, vector<int> b) | |
{ | |
auto i=a.begin(); | |
auto j=b.begin(); | |
auto k=a.end(); | |
auto l=b.end(); | |
vector<int> res; | |
for(;i!=k&&j!=l;++i,++j) | |
{ | |
res.push_back(*i-*j); | |
} | |
return res; | |
} | |
vector<int> plusv(vector<int> a, vector<int> b) | |
{ | |
auto i=a.begin(); | |
auto j=b.begin(); | |
auto k=a.end(); | |
auto l=b.end(); | |
vector<int> res; | |
for(;i!=k&&j!=l;++i,++j) | |
{ | |
res.push_back(*i+*j); | |
} | |
return res; | |
} | |
vector<int> read() | |
{ | |
vector<int> temp; | |
int n; | |
cin>>n; | |
for(int i=0;i<n;++i){ | |
int t; | |
cin>>t; | |
temp.push_back(t); | |
} | |
return temp; | |
} | |
class bankers | |
{ | |
public: | |
int r,c; | |
matrix allocated, total, need; | |
vector<int> avail; | |
bool request(int row, vector<int> req) | |
{ | |
for(int i=0;i<c;++i){ | |
if(req[i]>need.m[row][i]) | |
{ | |
cout<<"Request greater than need"; | |
return false; | |
} | |
if(req[i]>avail[i]) | |
{ | |
cout<<"Request greater than available"; | |
return false; | |
} | |
} | |
cout<<"\n Allocating resources to process "<<row<<" : "; | |
print(req); | |
avail = minusv(avail, req); | |
allocated.chrow(row,plusv(allocated.getRow(row),req)); | |
need.chrow(row,minusv(need.getRow(row),req)); | |
auto temp = safety(); | |
if(!temp.first) | |
{ | |
cout<<"\n Allocation is unsafe, rolling back changes"; | |
avail = plusv(avail, req); | |
allocated.chrow(row,minusv(allocated.getRow(row),req)); | |
need.chrow(row,plusv(need.getRow(row),req)); | |
} | |
else | |
{ | |
cout<<" new Safe sequence : "; | |
print(temp.second); | |
} | |
} | |
pair<bool,vector<int> > safety() | |
{ | |
vector<int> work= avail; | |
vector<bool> finish; | |
for(int i=0;i<r;++i) | |
finish.push_back(false); | |
vector<int> safeSequence; | |
while(find(finish.begin(),finish.end(),false)!=finish.end()){ | |
int row=need.find(work,finish); | |
if(row==-1){ | |
auto temp=*new pair<bool,vector<int> >; | |
temp.first=false; | |
temp.second=*new vector<int>; | |
return temp; | |
} | |
else | |
{ | |
for(int j=0;j<c;++j) | |
{ | |
work[j]+=allocated.m[row][j]; | |
} | |
finish[row]=true; | |
safeSequence.push_back(row); | |
} | |
} | |
auto temp=*new pair<bool,vector<int> >; | |
temp.first=true; | |
temp.second=safeSequence; | |
return temp; | |
} | |
bankers(matrix allocated, matrix total,vector<int> avail) | |
{ | |
this->r=allocated.r; | |
this->c=allocated.c; | |
this->allocated = allocated; | |
this->total = total; | |
this->avail = avail; | |
this->need = this->total - this->allocated; | |
auto safe = safety(); | |
if(!safe.first) | |
cout<<"Initial State is not safe\n"; | |
else | |
{ | |
cout<<"\nSafe sequence is : "; | |
print(safe.second); | |
} | |
} | |
void describe() | |
{ | |
cout<<endl; | |
cout<<"Allocated"<<endl; | |
allocated.print(); | |
cout<<endl<<"Total"<<endl; | |
total.print(); | |
cout<<endl<<"Need"<<endl; | |
need.print(); | |
cout<<endl<<"Available"<<endl; | |
print(avail); | |
} | |
}; | |
int main() | |
{ | |
freopen("input","r",stdin); | |
matrix al, tot; | |
al.read(); | |
tot.read(); | |
vector<int> res=read(); | |
bankers b(al,tot,res); | |
b.describe(); | |
int process; | |
cin>>process; | |
vector<int> req=read(); | |
b.request(process,req); | |
cout<<"After state"; | |
b.describe(); | |
return 0; | |
} | |
/* | |
INPUT | |
5 3 | |
0 1 0 | |
2 0 0 | |
3 0 2 | |
2 1 1 | |
0 0 2 | |
5 3 | |
7 5 3 | |
3 2 2 | |
9 0 2 | |
2 2 2 | |
4 3 3 | |
3 | |
3 3 2 | |
0 | |
3 | |
3 3 2 | |
OUTPUT | |
1th row : 1 2 2 | |
3 3 2 | |
3th row : 0 1 1 | |
5 3 2 | |
0th row : 7 4 3 | |
7 4 3 | |
2th row : 6 0 0 | |
7 5 3 | |
4th row : 4 3 1 | |
10 5 5 | |
Safe sequence is : 1 3 0 2 4 | |
Allocated | |
0 1 0 | |
2 0 0 | |
3 0 2 | |
2 1 1 | |
0 0 2 | |
Total | |
7 5 3 | |
3 2 2 | |
9 0 2 | |
2 2 2 | |
4 3 3 | |
Need | |
7 4 3 | |
1 2 2 | |
6 0 0 | |
0 1 1 | |
4 3 1 | |
Available | |
3 3 2 | |
Allocating resources to process 0 : 3 3 2 | |
Allocation is unsafe, rolling back changesAfter state | |
Allocated | |
0 1 0 | |
2 0 0 | |
3 0 2 | |
2 1 1 | |
0 0 2 | |
Total | |
7 5 3 | |
3 2 2 | |
9 0 2 | |
2 2 2 | |
4 3 3 | |
Need | |
7 4 3 | |
1 2 2 | |
6 0 0 | |
0 1 1 | |
4 3 1 | |
Available | |
3 3 2 | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*For compiling shit with threads in it, use -lpthread tag in g++*/ | |
#include<iostream> | |
/*Gonna use semaphores*/ | |
#include<semaphore.h> | |
/*Gonna use multithreading, each philosopher being a thread*/ | |
#include<pthread.h> | |
/*For thread control, not used currently*/ | |
#include<fcntl.h> | |
/*As always rest of the party*/ | |
#include<sys/types.h> | |
#include<unistd.h> | |
#include<stdlib.h> | |
#include<string> | |
#define max 6 | |
using namespace std; | |
/*Five semaphores for each of the chopsticks and a mutex for ensuring at least one philosopher eats*/ | |
sem_t chopstick[max],mutex; | |
/*A thread for each of the philosophers*/ | |
pthread_t philosopher[max]; | |
/*Eat will be the function called by the threads, the philosopher thinks, eats if available, and then thinks*/ | |
/*Another variation possible is it randomly thinks and randomly eats in an infinite loop*/ | |
void *eat(void *args) | |
{ | |
/*Number of chopsticks*/ | |
int *num = (int*) args; | |
int n = *num; | |
/*First wait*/ | |
cout<<"Waiting : " + to_string(n) + "\n"; | |
/*Try to get, i and i+1 mod 5 chopstick*/ | |
/*Sem wait is the same as wait() function of semaphore*/ | |
sem_wait(&chopstick[n]); | |
sem_wait(&chopstick[(n+1)%max]); | |
/*To ensure that deadlock does not occur at most max-1 philosophers will be able to go into eat state at the same time*/ | |
sem_wait(&mutex); | |
/*After eating, release all semaphore and go to think state*/ | |
cout<<"Eating : " + to_string(n) + "\n"; | |
sem_post(&mutex); | |
sem_post(&chopstick[(n+1)%max]); | |
sem_post(&chopstick[n]); | |
cout<<"Thinking : " + to_string(n) + "\n"; | |
} | |
using namespace std; | |
int main() | |
{ | |
/*Try initialising all chopsticks as one*/ | |
for(int i=0;i<max;++i) | |
{ | |
if(sem_init(&chopstick[i],0,1)==-1) | |
{ | |
cout<<"Error init"; | |
return -1; | |
} | |
} | |
/*init mutex as max-1*/ | |
if(sem_init(&mutex,0,max-1)==-1) | |
{ | |
cout<<"Error init"; | |
return -1; | |
} | |
/*Create an array to track indices (just passing i, had issues)*/ | |
/*If i sent i, in 0th iteration, the loop might have gone on and changed value of i, so basically i is stored somewhere else where it won't change*/ | |
int n[max]; | |
/*store i*/ | |
for (int i=0;i<max;++i) | |
n[i]=i; | |
/*Create max number of threads for each philosopher, on create call the eat method*/ | |
for(int i=0;i<max;++i) | |
{ | |
pthread_create(&philosopher[i],NULL,&eat,&n[i]); | |
} | |
/*After all threads complete, exit the program*/ | |
pthread_exit(NULL); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*Thread racing program, create n threads, make then increase by random numbers, when one gets its count to hundred, declare that thread to be the winner*/ | |
#include<iostream> | |
#include<sys/types.h> | |
#include<unistd.h> | |
/*Uses threads, so pthread library*/ | |
#include<pthread.h> | |
#include<stdlib.h> | |
using namespace std; | |
/*To know if at least one has crossed hundred, if it has don't print anymore*/ | |
bool over; | |
void *worker(void *args) | |
{ | |
/*Get the thread id from argument*/ | |
int *tid = (int*)args; | |
/*Start with 0*/ | |
int num=0; | |
/*While all threads are still racing and I'm not yet at 100*/ | |
while(!over && num<=100) | |
{ | |
/*Take a random step*/ | |
int inc = rand()%10+1; | |
num+=inc; | |
/*Did i win?*/ | |
if(num>100){ | |
/*If I win, declare the contest to have ended, and proclaim me as the winner*/ | |
over=true; | |
printf("%d : %d\n",*tid,num); | |
cout<<" Winner : "<<*tid<<endl; | |
} | |
/*Only print the number if someone hasn't won yet*/ | |
if(!over) | |
printf("%d : %d\n",*tid,num); | |
sleep(1); | |
} | |
} | |
int main() | |
{ | |
/*Create seven runners*/ | |
pthread_t a[7]; | |
/*Make id's for then (i changing issue as seen in dining philosopher)*/ | |
int id[7]={0,1,2,3,4,5,6}; | |
/*init over*/ | |
over=false; | |
/*On you marks, get set, GO*/ | |
for(int i=0;i<7;++i) | |
{ | |
pthread_create(&a[i],NULL,&worker,&id[i]); | |
} | |
/*Wait for the last guy*/ | |
pthread_exit(NULL); | |
/*Kill them all, Show no mercy*/ | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment