consolidate all repos to one for archive
This commit is contained in:
1
semester_2/uvod_v_operacijske_sisteme/README.md
Normal file
1
semester_2/uvod_v_operacijske_sisteme/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# Vaje
|
7
semester_2/uvod_v_operacijske_sisteme/dodatna/Makefile
Normal file
7
semester_2/uvod_v_operacijske_sisteme/dodatna/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
all: clean streznik odjemalnik
|
||||
streznik: streznik.cpp
|
||||
g++ -pthread -lrt streznik.cpp -o streznik
|
||||
odjemalnik: odjemalnik.cpp
|
||||
g++ -pthread -lrt odjemalnik.cpp -o odjemalnik
|
||||
clean:
|
||||
rm -f odjemalnik streznik vhod izhod izklop
|
21
semester_2/uvod_v_operacijske_sisteme/dodatna/README.md
Normal file
21
semester_2/uvod_v_operacijske_sisteme/dodatna/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
Nadzornik pomnilnika (samostojna naloga)
|
||||
|
||||
Pripravite program nadzornikPomnilnika, ki bo spremljal porabo pomnilnika v sistemu. Program naj deluje kot sistemski servis. Program naj spremlja in beleži trenutno stanje pomnilnika, drugim programom pa preko poljubne medprocesne komunikacije omogoča dostop do meritev in konfiguracijo zajemanja.
|
||||
|
||||
Trenutno stanje pomnilnika lahko preberete iz zbirke /proc/meminfo (poiščite meminfo v dokumentaciji man 5 proc za podroben opis vsebine). V njen je zapisanih precej podrobnosti, vaš servis naj spremlja in beleži vsaj:
|
||||
|
||||
količino celotnega pomnilnika
|
||||
količino prostega pomnilnika
|
||||
količino pomnilnika na voljo procesom
|
||||
količino celotnega swap prostora
|
||||
količino prostega swap prostora
|
||||
|
||||
Servis ima dva parametra zajemanja: čas med branji in število hranjenih meritev. Čas med branji določa koliko časa sevis počaka med branji /proc/meminfo. Število hranjenih meritev pa določa koliko zadnjih prebranih vrednosti si servis zapomne.
|
||||
|
||||
Servis naj preko poljubne tehnike medprocesne komunikacije omogoča komunikacijo z različnimi odjemalci. Odjemalci lahko spreminjajo oba parametra, pridobijo trenutno hranjeno zgodovino in ustavijo servis. Servis mora omogočati komunikacijo z več odjemalci hkrati in ostati odziven. Priporočamo, da uporabite vsaj dve niti. Eno za branje /proc/meminfo in eno ali več za komunikacijo z odjemalci.
|
||||
|
||||
Za komunikacijo boste potrebovali en kanal (cev, vrsto za sporočila, itd. ), na katerem se odjemalci povežejo na servis. Za vsakega odjemalca mora nato servis ustvariti nov kanal preko katerega komunicira s tistim odjemalcem.
|
||||
|
||||
Pripravite tudi primer odjemalca. Le ta naj omogoča pošiljanje zahtev servisu in izpis vrnjenih vrednosti (na primer zgodovine porabe pomnilnika).
|
||||
|
||||
Servis lahko poženete v enem terminalu, odjemalce pa v drugih. Ne rabite pripravljati resničnega sistemskega servisa
|
69
semester_2/uvod_v_operacijske_sisteme/dodatna/odjemalnik.cpp
Normal file
69
semester_2/uvod_v_operacijske_sisteme/dodatna/odjemalnik.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <list>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
void menu(){
|
||||
std::cout << "1. Zamenjaj argumente\n";
|
||||
std::cout << "2. Pridobi stanje\n";
|
||||
std::cout << "3. Izklopi streznik\n";
|
||||
std::cout << "4. konec\n";
|
||||
std::cout << "Izbira: ";
|
||||
}
|
||||
|
||||
int main(){
|
||||
int izbira, l;
|
||||
int runn = 1;
|
||||
int arry[2];
|
||||
int cev1, cev2, cev3;
|
||||
int closep = 6;
|
||||
unsigned long array[100];
|
||||
while (runn == 1)
|
||||
{
|
||||
menu();
|
||||
std::cin >> izbira;
|
||||
switch (izbira){
|
||||
case 1:
|
||||
std::cout << "Vspisi dely v sekundah: ";
|
||||
std::cin >> arry[0];
|
||||
std::cout << "Vspisi stevilo branj: ";
|
||||
std::cin >> arry[1];
|
||||
cev1 = open("vhod", O_WRONLY);
|
||||
write(cev1, &arry, sizeof(arry));
|
||||
close(cev1);
|
||||
break;
|
||||
case 2:
|
||||
cev2 = open("izhod", O_RDONLY);
|
||||
if(cev2 < 0) std::cout << "tezava pri odpiranju cevi 0\n";
|
||||
l = read(cev2, &array, sizeof(array));
|
||||
if(l<0) std::cout << "tezava pri branju cevi \n";
|
||||
for (int i = 0; i < 100; i += 5){
|
||||
if(array[i] != 0)
|
||||
std::cout << array[i] << " " << array[i+1] << " " << array[i+2] << " " << array[i+3] << " " << array[i+4] << "\n";
|
||||
}
|
||||
std::cout << "\n";
|
||||
if(close(cev2) != 0) std::cout << "tezava pri zapiranju cevi 0\n";
|
||||
break;
|
||||
case 3:
|
||||
cev3 = open("izklop", O_WRONLY);
|
||||
write(cev3, &closep, sizeof(closep));
|
||||
close(cev3);
|
||||
runn = 0;
|
||||
break;
|
||||
default:
|
||||
runn = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
180
semester_2/uvod_v_operacijske_sisteme/dodatna/streznik.cpp
Normal file
180
semester_2/uvod_v_operacijske_sisteme/dodatna/streznik.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
struct SystemInfo{
|
||||
unsigned long memTotal;
|
||||
unsigned long memFree;
|
||||
long upTime;
|
||||
unsigned long swapTotal;
|
||||
unsigned long swapFree;
|
||||
};
|
||||
|
||||
struct MesData{
|
||||
unsigned int size, delay;
|
||||
};
|
||||
|
||||
struct MesData mezureData;
|
||||
std::list<SystemInfo> listSI;
|
||||
int running = 1;
|
||||
int icev1, icev2, icev3;
|
||||
pthread_t tid[4];
|
||||
|
||||
void* glavna(void* arg){
|
||||
int i, l;
|
||||
while (running == 1){
|
||||
icev3 = open("izklop",O_RDONLY);
|
||||
if(icev3 < 0) std::cout << "tezava pri odpiranju cevi 2\n";
|
||||
|
||||
l = read(icev3, &i, sizeof(i));
|
||||
if(l<0) std::cout << "tezava pri branju cevi 2\n";
|
||||
|
||||
if(i > 2){
|
||||
pthread_cancel(tid[2]);
|
||||
pthread_cancel(tid[3]);
|
||||
running = 0;
|
||||
}
|
||||
|
||||
if(close(icev3) != 0) std::cout << "tezava pri zapiranju cevi 0\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* mezuringNode(void* arg){
|
||||
struct sysinfo si;
|
||||
struct SystemInfo info;
|
||||
unsigned int microsecond = 1000000;
|
||||
while (running == 1)
|
||||
{
|
||||
sysinfo (&si);
|
||||
info.memTotal = si.totalram;
|
||||
info.memFree = si.freeram;
|
||||
info.upTime = si.uptime;
|
||||
info.swapFree = si.freeswap;
|
||||
info.swapTotal = si.totalswap;
|
||||
listSI.push_front(info);
|
||||
while(listSI.size() > mezureData.size){
|
||||
listSI.pop_back();
|
||||
}
|
||||
usleep(mezureData.delay * microsecond);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* input(void* arg){
|
||||
int tmp[2];
|
||||
int l;
|
||||
while(running == 1){
|
||||
|
||||
icev1 = open("vhod",O_RDONLY);
|
||||
if(icev1 < 0) std::cout << "tezava pri odpiranju cevi 0\n";
|
||||
|
||||
l = read(icev1, &tmp, sizeof(tmp));
|
||||
if(l<0) std::cout << "tezava pri branju cevi 0\n";
|
||||
|
||||
std::cout << tmp[0] << " " << tmp[1] << "\n";
|
||||
mezureData.delay = tmp[0];
|
||||
mezureData.size = tmp[1];
|
||||
|
||||
if(close(icev1) != 0) std::cout << "tezava pri zapiranju cevi 0\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* output(void* arg){
|
||||
unsigned long array[100];
|
||||
int l, i = 0;
|
||||
|
||||
while(running == 1){
|
||||
icev2 = open("izhod",O_WRONLY);
|
||||
if(icev2 < 0)
|
||||
std::cout << "Napaka pri odprtju cevi 1\n";
|
||||
else
|
||||
std::cout << "Odprta cevi 1\n";
|
||||
|
||||
i = 0;
|
||||
for (auto& elm : listSI){
|
||||
array[i] = elm.memTotal;
|
||||
i++;
|
||||
array[i] = elm.memFree;
|
||||
i++;
|
||||
array[i] = elm.upTime;
|
||||
i++;
|
||||
array[i] = elm.swapFree;
|
||||
i++;
|
||||
array[i] = elm.swapTotal;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
l = write(icev2, &array, sizeof(array));
|
||||
if(l < 0)
|
||||
std::cout << "tezave pri pisanju v cev\n";
|
||||
else
|
||||
std::cout << "Vpisano v cevi 1\n";
|
||||
|
||||
if(close(icev2) != 0)
|
||||
std::cout << "tezava pri zapiranju cevi 1\n";
|
||||
else
|
||||
std::cout << "Zaprta cevi 1\n";
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
std::cout << "Hello World\n";
|
||||
|
||||
mezureData.delay = 1;
|
||||
mezureData.size = 4;
|
||||
|
||||
mkfifo("vhod", S_IRUSR|S_IWUSR);
|
||||
mkfifo("izhod", S_IRUSR|S_IWUSR);
|
||||
mkfifo("izklop", S_IRUSR|S_IWUSR);
|
||||
|
||||
pthread_create(&tid[0], NULL, glavna, NULL);
|
||||
pthread_create(&tid[1], NULL, mezuringNode, NULL);
|
||||
pthread_create(&tid[2], NULL, input, NULL);
|
||||
pthread_create(&tid[3], NULL, output, NULL);
|
||||
|
||||
pthread_join(tid[0], NULL);
|
||||
pthread_join(tid[1], NULL);
|
||||
pthread_join(tid[2], NULL);
|
||||
pthread_join(tid[3], NULL);
|
||||
|
||||
std::string str;
|
||||
char* strc;
|
||||
for (auto& elm : listSI){
|
||||
str += "TotalMemory: " + std::to_string(elm.memTotal) + " ";
|
||||
str += "FreeMemory: " + std::to_string(elm.memFree) + " ";
|
||||
str += "UpTime: " + std::to_string(elm.upTime) + " ";
|
||||
str += "FreeSwap: " + std::to_string(elm.swapFree) + " ";
|
||||
str += "TotalSwap: " + std::to_string(elm.swapTotal) + "\n";
|
||||
}
|
||||
strc = &str[0];
|
||||
|
||||
printf("%s",strc);
|
||||
|
||||
close(icev1);
|
||||
close(icev2);
|
||||
close(icev3);
|
||||
|
||||
unlink("vhod");
|
||||
unlink("izhod");
|
||||
unlink("izklop");
|
||||
|
||||
return 0;
|
||||
}
|
69
semester_2/uvod_v_operacijske_sisteme/naloga_01/README.md
Normal file
69
semester_2/uvod_v_operacijske_sisteme/naloga_01/README.md
Normal file
@@ -0,0 +1,69 @@
|
||||
Osnovni ukazi v lupini Bash (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo nekaj osnovnih ukazov v lupini Bash. Pripravite 10 skript, ki izvedejo v nadaljevanju opisane naloge.
|
||||
|
||||
Na sistem oddajte .zip paket z 10 skriptami: naloga_1.sh, naloga_2.sh, ..., naloga_10.sh. Bodite pozorni na poimenovanja, ta morajo točno ustrezati predpisanim naslovom. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1.sh
|
||||
|
||||
predvideni ukazi: ls
|
||||
|
||||
Uporabite ukaz ls, da izpišete vsebino trenutnega kazala v zbirčnem sistemu. Izpis naj vsebuje tudi skrite zbirke in kazala, vendar ne '.' in '..'. Izpis naj bo v obliki preprostega seznama brez podrobnosti.
|
||||
naloga_2.sh
|
||||
|
||||
predvideni ukazi: ls, wc, echo, operator |
|
||||
|
||||
Izpišite število zbirk in kazal na vaši trenutni lokaciji. To dosežete tako, da izhod ukaza ls preusmerite v ukaz wc. Izpis opremite tudi z ustreznim sporočilom, da bo izgledal kot:
|
||||
|
||||
število zbirk in kazal:
|
||||
10
|
||||
|
||||
naloga_3.sh
|
||||
|
||||
predvideni ukazi: mkdir, cd, pwd
|
||||
|
||||
Ustvarite kazalo/mapo "Slike". Pomaknite se v to kazalo in izpišite celotno pot na kateri se v tem kazalu nahajate.
|
||||
naloga_4.sh
|
||||
|
||||
predvideni ukazi: mkdir, echo, touch, cat, operatorja preusmeritev > in >>
|
||||
|
||||
Ustvarite kazalo "Datoteke". Znotraj tega kazala usvarite zbirko pozdravi.txt. V to zbirko najprej zapišite vrstico "pozdravljen". Nato pa dodajte še vrstico "dober dan". Nato izpišite vsebino zbirke pozdravi.txt.
|
||||
naloga_5.sh
|
||||
|
||||
predvideni ukazi: mkdir, touch, mv, rm, ls
|
||||
|
||||
Ustvarite kazalo "A" in kazalo "B".
|
||||
Znotraj kazala "A" ustvarite zbirke "a", "b", "c".
|
||||
Premaknite zbirke "a" in "c" v kazalo "B".
|
||||
Rekurzivno izpišite vsebino izvornega kazala, tako da boste videli kazala "A", "B" in zbirke "a", "b" in "c".
|
||||
Izbrišite kazalo "B" skupaj z zbirkami "a" in "c".
|
||||
Ponovno rekurzivno izpišite vsebino izvornega kazala.
|
||||
|
||||
naloga_6.sh
|
||||
|
||||
predvideni ukazi: head, tail, echo
|
||||
|
||||
Okrajšajte izpis zbirke "/proc/meminfo". Najprej izpišite prve 3 vrstice zbirke. Nato izpišite 3 pike, vsako v svoji vrstici. Nato izpišite zadnje 3 vrstice zbirke.
|
||||
naloga_7.sh
|
||||
|
||||
predvideni ukazi: ls, head, tail, preusmerjanje |
|
||||
|
||||
Izpišite 10 največjih programov v sistemu v poti /usr/bin. Izpišite tudi njihove velikosti v berljivi obliki. Bodite pozorni, da odstranite ali ustrezno upoštevate dodatne vrstice, ki vam jih izpiše ukaz ls. Z ukazom ls ne uporabite zastavice -l.
|
||||
naloga_8.sh
|
||||
|
||||
predvideni ukazi: touch, ls
|
||||
|
||||
Ustvarite zbirko zgodovina_linux_jedra, in nastavite njen čas zadnje spremembe (ang. modification) na 17 september, 1991.
|
||||
naloga_9.sh
|
||||
|
||||
predvideni ukazi: ls, head, tail
|
||||
|
||||
Izpišite 10 najstarejših kazal ali zbirk (glede na datum zadnje spremembe), ki jih najdete v /tmp v vrstnem redu od najstarejše do najnovejše. Zopet bodite pozorni, da res izpišete 10 zbirk. Z ukazom ls ne uporabite zastavice -l.
|
||||
naloga_10.sh
|
||||
|
||||
predvideni ukazi: mv, ls, ujemanje vzorcev v bash (pattern matching)
|
||||
|
||||
Najprej izpišite podroben seznam zbirk kazala A in kazala B.
|
||||
Nato vsebino kazala A premaknite in združite z vsebino kazala B.
|
||||
Za zbirke z istim imenom poskrbite, da se prenesejo samo takrat, kadar je zbirka v kazalu A novejša.
|
||||
V takšnih primerih naj originalna zbirka v B dobi končnico "_stara", da se ne izgubi.
|
||||
Po združevanju izpišite seznam zbirk iz A, ki se niso premaknile in seznam zbirk iz B, ki so bile prepisane (torej seznam zbirk, ki imajo končnico "_stara").
|
@@ -0,0 +1 @@
|
||||
ls -A
|
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
ls -a A
|
||||
ls -a B
|
||||
mv -n A/* B
|
||||
mv -f -u --backup --suffix="_stara" A/* B
|
||||
ls -a A
|
||||
ls -a B | grep '\_stara$'
|
@@ -0,0 +1,2 @@
|
||||
echo število zbirk in kazal
|
||||
ls -A | wc -l
|
@@ -0,0 +1,3 @@
|
||||
mkdir Slike
|
||||
cd Slike
|
||||
pwd
|
@@ -0,0 +1,5 @@
|
||||
mkdir Datoteke
|
||||
cd Datoteke
|
||||
echo pozdravljen > pozdravi.txt
|
||||
echo dober dan >> pozdravi.txt
|
||||
cat pozdravi.txt
|
11
semester_2/uvod_v_operacijske_sisteme/naloga_01/naloga_5.sh
Normal file
11
semester_2/uvod_v_operacijske_sisteme/naloga_01/naloga_5.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
mkdir A
|
||||
mkdir B
|
||||
touch A/a
|
||||
touch A/b
|
||||
touch A/c
|
||||
mv A/a B/
|
||||
mv A/c B/
|
||||
ls -R
|
||||
rm -r B
|
||||
ls -R
|
||||
|
@@ -0,0 +1,5 @@
|
||||
head -3 /proc/meminfo
|
||||
echo .
|
||||
echo .
|
||||
echo .
|
||||
tail -3 /proc/meminfo
|
@@ -0,0 +1 @@
|
||||
ls -sSh /usr/bin | head -11 | tail
|
@@ -0,0 +1 @@
|
||||
touch -d '17 September 1991 00:00' zgodovina_linux_jedra
|
@@ -0,0 +1 @@
|
||||
ls -tr /tmp | head
|
59
semester_2/uvod_v_operacijske_sisteme/naloga_02/README.md
Normal file
59
semester_2/uvod_v_operacijske_sisteme/naloga_02/README.md
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
Napredni ukazi lupine Bash (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo izbranih kompleksnejših ukazov v lupini Bash. Pripravite 6 skript, ki izvedejo v nadaljevanju opisane naloge.
|
||||
|
||||
Na sistem oddajte .zip paket z 6 skriptami: naloga_1.sh, naloga_2.sh, ..., naloga_6.sh. Bodite pozorni na poimenovanja, ta morajo točno ustrezati predpisanim naslovom. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1.sh
|
||||
|
||||
predvideni ukazi: wc, sort, operator |
|
||||
|
||||
Z ukazom wc preštejte število besed v zbirkah uvod.txt, jedro.txt in zakljucek.txt, ki se nahajajo v trenutnem kazalu. Rezultat uredite od najmanj do največ besed.
|
||||
naloga_2.sh
|
||||
|
||||
predvideni ukazi: grep
|
||||
|
||||
Preštejte kolikokrat se v različnih zbirkah z izvorno kodo (končnica .cpp) v trenutnem kazalu pojavi spremenljivka "stevec".
|
||||
naloga_3.sh
|
||||
|
||||
predvideni ukazi: find
|
||||
|
||||
Izpišite tista kazala (ang. directory), katerih ime se zaključi z znakom _ in številom.
|
||||
naloga_4.sh
|
||||
|
||||
predvideni ukazi: ls, sort, operator |
|
||||
|
||||
V kazalu SlikeIzletov, se nahajajo slike, poimenovane po sistemu:
|
||||
|
||||
<izlet>_<mesec>_<leto>_dan_<dan_izleta>_<cas dneva>.jpg
|
||||
|
||||
Primeri takšnih slik:
|
||||
|
||||
Dunaj_Dec_2000_dan_1_13:00.jpg
|
||||
Rim_Jan_2001_dan_1_08:30.jpg
|
||||
Rim_Jan_2001_dan_1_13:00.jpg
|
||||
Rim_Jan_2001_dan_2_08:00.jpg
|
||||
|
||||
Izpišite seznam slik, kjer bodo slike urejene v kronološkem vrstnem redu. Najprej je potrebno urediti slike po letu in mesecu, v katerem so bile zajete (dva izleta sta lahko v istem letu, ne pa istem mesecu). Nato po dnevu izleta in nazadnje še po času.
|
||||
naloga_5.sh
|
||||
|
||||
predvideni ukazi: grep
|
||||
|
||||
Pripravite izpis deklaracij vseh funkcij v različnih zbirkah z izvorno kodo (končnice .c in .cpp) v trenutnem kazalu, ki kot argument prejmejo dve števili in vrnejo število. Oba argumenta in vrnjena vrednost so istega tipa: int, long, float ali double. Izpišite samo deklaracije funkcij, brez imen zbirk ali vrstic.
|
||||
|
||||
Primer izpisa:
|
||||
|
||||
int sestej(int, int);
|
||||
float zmnozi(float a, float b){
|
||||
long izracunaj(long val_1,long val_2);
|
||||
double deli(double x, double y);
|
||||
|
||||
naloga_6.sh
|
||||
|
||||
predvideni ukazi: find
|
||||
|
||||
V trenutnem kazalu in podkazalih poiščite vse izvedljive zbirke (programe, ang. executable), katerih ime se prične s "test_" ali "izpit_". Za vsako takšno zbirko izpišite njeno ime in pot do zbirke v obliki:
|
||||
|
||||
<ime> -> <pot>
|
||||
|
||||
|
@@ -0,0 +1 @@
|
||||
wc -w *.txt | sort -g
|
@@ -0,0 +1 @@
|
||||
grep -c stevec *.cpp
|
@@ -0,0 +1 @@
|
||||
find -name '*_[0-9]' -type d
|
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
cd SlikeIzletov
|
||||
ls *.jpg | sort -t_ -k3n -k2M -k5n -k6
|
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
grep -hEri --include=*.cpp --include=*.c -e '.*double.*\(double.*,\s+double.*\)' -e '.*float.*\(float.*,\s+float.*\)' -e '.*long.*\(long.*,\s+long.*\)' -e '.*int.*\(int.*,\s+int.*\)'
|
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
find \( -name 'izpit_*' -o -name 'test_*' \) -type f -executable -printf "%f -> %h\n"
|
52
semester_2/uvod_v_operacijske_sisteme/naloga_03/README.md
Normal file
52
semester_2/uvod_v_operacijske_sisteme/naloga_03/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
Programiranje v Bash (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte poznavanje programiranja v lupini Bash. Pripravite 6 skript, ki izvedejo v nadaljevanju opisane naloge.
|
||||
|
||||
Na sistem oddajte .zip paket s 6 skriptami: naloga_1.sh, naloga_2.sh, ..., naloga_6.sh. Bodite pozorni na poimenovanja, ta morajo točno ustrezati predpisanim naslovom. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1.sh
|
||||
|
||||
Skripta bo prejela dva argumenta z ukazne vrstice. Ta argumenta preberete kot spremenljivki $1 in $2. V spremenljivko a zapišite niz:
|
||||
|
||||
"prejeli smo <prvi argument> in <drugi argument>"
|
||||
|
||||
Z ukazom echo nato izpišite vsebino spremenljivke a. Primer uporabe:
|
||||
|
||||
$ bash naloga_1.sh nekaj drugega
|
||||
prejeli smo nekaj in drugega
|
||||
|
||||
naloga_2.sh
|
||||
|
||||
Izhod ukaza ls shranite v spremenljivko kot tabelo. S pomočjo indeksiranja izpišite prve tri elemente (prve tri vnose, ki jih izpiše ls). Nato izpišite besedo "itd.".
|
||||
naloga_3.sh
|
||||
|
||||
Skripta bo prejela tri argumente. Za vsak argument preverite ali je veljavna pot do zbirke in ali imate pravico prebrati njeno vsebino. V kolikor jo lahko, izpišite njeno vsebino s cat. Izpišite tudi kratko sporočilo:
|
||||
|
||||
<pot do zbirke>:
|
||||
<vsebina>
|
||||
|
||||
V nasprotnem primeru izpišite ustrezno opozorilo:
|
||||
|
||||
<pot do zbirke> ni veljavna zbirka
|
||||
|
||||
ali
|
||||
|
||||
<pot do zbirke> ni mogoce brati
|
||||
|
||||
naloga_4.sh
|
||||
|
||||
Z zanko obdelajte vse argumente, ki so skripti podani preko ukazne vrstice. Za vsak argument preverite ali ima končnico sh. V tem primeru ga izvedite kot skripto, z ukazom bash.
|
||||
naloga_5.sh
|
||||
|
||||
Izpišite vse zbirke v trenutnem kazalu tako, da ločite ime in končnico zbirke. Za zbirke zbirka_1.sh, zbirka_2.db.ext, zbirka_3.ext pričakujemo izpis:
|
||||
|
||||
$ bash naloga_5.sh
|
||||
zbirka_1 ima koncnico sh
|
||||
zbirka_2.db ima koncnico ext
|
||||
zbirka_3 ima koncnico ext
|
||||
|
||||
naloga_6.sh
|
||||
|
||||
V kazalu Slike najdete slike, katere je fotoaparat poimenoval z časom zajema. Imena so v obliki YYYYMMDD_hhmmss.jpg, kjer je YYYY leto, MM mesec, DD dan, hh ura, mm minuta in ss sekunda zajema.
|
||||
|
||||
Ustvarite ustrezna kazala in razvrstite slike v poti: Slike/YYYY/MM/DD/hh_mm_ss.jpg.
|
||||
|
@@ -0,0 +1,2 @@
|
||||
a="prejeli smo $1 in $2"
|
||||
echo $a
|
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
array=($(ls))
|
||||
echo ${array[0]}
|
||||
echo ${array[1]}
|
||||
echo ${array[2]}
|
||||
echo itd.
|
39
semester_2/uvod_v_operacijske_sisteme/naloga_03/naloga_3.sh
Normal file
39
semester_2/uvod_v_operacijske_sisteme/naloga_03/naloga_3.sh
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
if [ -f "$1" ]
|
||||
then
|
||||
if [ -r "$1" ]
|
||||
then
|
||||
echo $1
|
||||
cat $1
|
||||
else
|
||||
echo "$1 ni mogoce brati"
|
||||
fi
|
||||
else
|
||||
echo "$1 ni veljavna zbirka"
|
||||
fi
|
||||
|
||||
if [ -f "$2" ]
|
||||
then
|
||||
if [ -r "$2" ]
|
||||
then
|
||||
echo $2
|
||||
cat $2
|
||||
else
|
||||
echo "$2 ni mogoce brati"
|
||||
fi
|
||||
else
|
||||
echo "$2 ni veljavna zbirka"
|
||||
fi
|
||||
|
||||
if [ -f "$3" ]
|
||||
then
|
||||
if [ -r "$3" ]
|
||||
then
|
||||
echo $3
|
||||
cat $3
|
||||
else
|
||||
echo "$3 ni mogoce brati"
|
||||
fi
|
||||
else
|
||||
echo "$3 ni veljavna zbirka"
|
||||
fi
|
@@ -0,0 +1,8 @@
|
||||
dat=($(ls))
|
||||
for datoteka in ${dat[@]}
|
||||
do
|
||||
if [[ $datoteka == *.sh ]]
|
||||
then
|
||||
bash $datoteka
|
||||
fi
|
||||
done
|
@@ -0,0 +1,5 @@
|
||||
dat=($(ls))
|
||||
for dato in ${dat[@]}
|
||||
do
|
||||
echo ${dato%.*} " ima koncnico " ${dato##*.}
|
||||
done
|
22
semester_2/uvod_v_operacijske_sisteme/naloga_03/naloga_6.sh
Normal file
22
semester_2/uvod_v_operacijske_sisteme/naloga_03/naloga_6.sh
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
cd Slike/
|
||||
slike=($(ls))
|
||||
for slika in ${slike[@]}
|
||||
do
|
||||
if [[ ! -d "./${slika:0:4}" ]]
|
||||
then
|
||||
$(mkdir ./${slika:0:4})
|
||||
fi
|
||||
if [[ ! -d "./${slika:0:4}/${slika:4:2}" ]]
|
||||
then
|
||||
$(mkdir ./${slika:0:4}/${slika:4:2})
|
||||
fi
|
||||
if [[ ! -d "./${slika:0:4}/${slika:4:2}/${slika:6:2}" ]]
|
||||
then
|
||||
$(mkdir ./${slika:0:4}/${slika:4:2}/${slika:6:2})
|
||||
fi
|
||||
if [[ -d "./${slika:0:4}/${slika:4:2}/${slika:6:2}" ]]
|
||||
then
|
||||
$(mv -f ./$slika ./${slika:0:4}/${slika:4:2}/${slika:6:2}/${slika:9:2}"_"${slika:11:2}"_"${slika:13:2}.jpg )
|
||||
fi
|
||||
done
|
12
semester_2/uvod_v_operacijske_sisteme/naloga_04/Makefile
Normal file
12
semester_2/uvod_v_operacijske_sisteme/naloga_04/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
all: naloga_1 naloga_2 naloga_3
|
||||
naloga_1: naloga_1.c
|
||||
gcc naloga_1.c -o naloga_1
|
||||
rm naloga_1.c
|
||||
naloga_2: naloga_2.c
|
||||
gcc naloga_2.c -o naloga_2
|
||||
rm naloga_2.c
|
||||
naloga_3: naloga_3.c
|
||||
gcc naloga_3.c -o naloga_3
|
||||
rm naloga_3.c
|
||||
clean:
|
||||
rm -f naloga_1 naloga_2 naloga_3
|
47
semester_2/uvod_v_operacijske_sisteme/naloga_04/README.md
Normal file
47
semester_2/uvod_v_operacijske_sisteme/naloga_04/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
Branje in pisanje z oprimki (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo oprimkov in ustreznih funkcij za pisanje in branje iz različnih virov. Pripravite 3 programe, ki izvedejo v nadaljevanju opisane naloge.
|
||||
|
||||
Pripravite tudi Makefile, ki bo vašo kodo prevedel v izvedljive programe. Posamezni naslov podnaloge v nadaljevanu so sestavljeni iz pričakovanega imena programa (mora biti tako) in pričakovanega imena izvorne zbirke (to je lahko drugačno, dokler jih vaš Makefile pravilno prevede).
|
||||
|
||||
Na sistem oddajte .zip paket z Makefile skripto in izvornimi zbirkami. Bodite pozorni na poimenovanja. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1 (naloga_1.c)
|
||||
|
||||
Programu bo v prvem argumentu podana pot do zbirke. Zbirko odprite, preberite vsebino in preštejte število pojavitev simbola 'a'. Na koncu izpišite prešteto število ponovitev. Velikosti zbirke ne boste mogli določiti vnaprej, brati morate dokler ne prejmete informacije o koncu zbirke.
|
||||
naloga_2 (naloga_2.c)
|
||||
|
||||
Program bo v prvih treh argumentih prejel eno celo število, eno realno število in še eno celo število. Te lahko iz simbolov pretvorite v vrednosti z:
|
||||
|
||||
int i = atoi(argv[1]);
|
||||
float j = atof(argv[2]);
|
||||
int k = atoi(argv[3]);
|
||||
|
||||
Ta števila izpišite v formatirani obliki. Za formatiranje morate uporabiti funkcijo printf. Ne smete implementirati lastnega formatiranja z if stavki in zankami.
|
||||
|
||||
Za prvo število naj izpiše vsaj tri števke, krajša števila pa naj z leve zapolni z 0. Pred število naj vedno izpiše + za pozitivna in - za negativna števila.
|
||||
|
||||
Za drugo število naj izpiše 3 decimalna mesta.
|
||||
|
||||
Za tretje število naj bo izpis v hexadecimalni obliki z 0x simbolom na začetku.
|
||||
|
||||
Primer izpisa:
|
||||
|
||||
$ ./naloga_2 4 12.0532154 255
|
||||
int: +004
|
||||
float: 12.053
|
||||
hex: 0xFF
|
||||
|
||||
naloga_3 (naloga_3.c)
|
||||
|
||||
Program naj s standardnega vhoda bere binarne podatke, v obliki strukture: struct {char[4], short, int}. V 4 znakih je opisan format (brez 0 na koncu), nato v short sledi glavna verzija in v int manjša verzija.
|
||||
Vsak prejet podatek naj izpiše kot formatiran niz:
|
||||
|
||||
<opis> = <večja verzija>.<manjša verzija>
|
||||
|
||||
Program se zaključi ko prebere celotno vsebino vhoda. Primer izpisov:
|
||||
|
||||
JPEG = 2.14
|
||||
PNG = 0.5
|
||||
WEBM = 66.6
|
||||
|
||||
|
19
semester_2/uvod_v_operacijske_sisteme/naloga_04/naloga_1.c
Normal file
19
semester_2/uvod_v_operacijske_sisteme/naloga_04/naloga_1.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int args, char** argv) {
|
||||
int file = open(argv[1], O_RDONLY, 0);
|
||||
char crka[1];
|
||||
int stevc = 0, konec = 1;
|
||||
while (konec != 0) {
|
||||
konec = read(file, crka, 1);
|
||||
if (crka[0] == 'a') stevc += 1;
|
||||
}
|
||||
printf("Ponovitev a: %d \n", stevc);
|
||||
close(file);
|
||||
return 0;
|
||||
}
|
13
semester_2/uvod_v_operacijske_sisteme/naloga_04/naloga_2.c
Normal file
13
semester_2/uvod_v_operacijske_sisteme/naloga_04/naloga_2.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main (int argc, char** argv){
|
||||
printf("int: %+04d \n",atoi(argv[1]));
|
||||
printf("float: %.3f \n",atof(argv[2]));
|
||||
printf("hex: 0x%x \n",atoi(argv[3]));
|
||||
return 0;
|
||||
}
|
19
semester_2/uvod_v_operacijske_sisteme/naloga_04/naloga_3.c
Normal file
19
semester_2/uvod_v_operacijske_sisteme/naloga_04/naloga_3.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct data {
|
||||
char description[4];
|
||||
short shorter;
|
||||
int num;
|
||||
};
|
||||
|
||||
int main(int args, char **argv, struct data prebrano) {
|
||||
while (read(0, &prebrano, sizeof(struct data))) {
|
||||
printf("%.4s = %hi.%d\n", prebrano.description, prebrano.shorter, prebrano.num);
|
||||
}
|
||||
return 0;
|
||||
}
|
9
semester_2/uvod_v_operacijske_sisteme/naloga_05/Makefile
Normal file
9
semester_2/uvod_v_operacijske_sisteme/naloga_05/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
all: naloga_1 naloga_2
|
||||
naloga_1: naloga_1.c
|
||||
gcc naloga_1.c -pthread -o naloga_1
|
||||
rm naloga_1.c
|
||||
naloga_2: naloga_2.c
|
||||
gcc naloga_2.c -pthread -o naloga_2
|
||||
rm naloga_2.c
|
||||
clean:
|
||||
rm -f naloga_1 naloga_2
|
67
semester_2/uvod_v_operacijske_sisteme/naloga_05/README.md
Normal file
67
semester_2/uvod_v_operacijske_sisteme/naloga_05/README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
Niti (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo knjižnice pthread za niti. Pripravite 3 programe, ki izvedejo v nadaljevanju opisane naloge. Pripravite tudi Makefile, ki bo vašo kodo prevedel v izvedljive programe.
|
||||
|
||||
Posamezni naslov podnaloge v nadaljevanu so sestavljeni iz pričakovanega imena programa in pričakovanega imena izvorne zbirke.
|
||||
|
||||
Na sistem oddajte .zip paket z Makefile skripto in izvornimi zbirkami. Bodite pozorni na poimenovanja. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1 (naloga_1.c)
|
||||
|
||||
Vaš program bo prejel parametre preko ukazne vrstice v obliki:
|
||||
|
||||
$ ./naloga_1 <milisekunde> <sporocilo> <milisekunde> <sporocilo> ...
|
||||
|
||||
Milisekunde so vedno cela števila.
|
||||
|
||||
Za vsak par argumentov milisekunde in sporočilo naj program ustvari novo nit. Nit naj najprej počaka podano število milisekund nato pa izpiše svojo zaporedno število in sporočilo. Glavna nit mora seveda počakati vse ustvarjene niti. Niti bo največ 10.
|
||||
|
||||
Primer zagona in izpisa:
|
||||
|
||||
$ ./naloga_1 300 konec 100 zacetek 200 jedro
|
||||
nit 2: zacetek
|
||||
nit 3: jedro
|
||||
nit 1: konec
|
||||
|
||||
naloga_2 (naloga_2.c)
|
||||
|
||||
Vaš program bo prejel poti do 3 zbirk (pravzaprav bodo to imenovane cevi). Te zbirke odprite samo za branje. Za vsako pot ustvarite svojo nit, ki bo iz podanega vira prebrala 10 znakov dolgo sporočilo. Vsaka nit naj izpiše prebrano sporočilo skupaj s svojim zaporednim številom. Sporočilo naj vrne glavni niti.
|
||||
|
||||
Glavna nit naj po zaključku vseh ustvarjenih niti izpiše vsa tri sporočila kot eno sporočilo.
|
||||
|
||||
Primer zagona in izpisa:
|
||||
|
||||
$ ./naloga_2 ./zbirka_1 ./zbira_2 ./zbirka_3
|
||||
nit 3: ih_______
|
||||
nit 1: sporocilo_
|
||||
nit 2: v_treh_kos
|
||||
|
||||
glavna nit: sporocilo_v_treh_kosih_______
|
||||
|
||||
naloga_3 (naloga_3.c)
|
||||
|
||||
Implementiranje program, ki pospeši seštevanje vrednosti s pomočjo niti. Kot parametri ukazne vrstice bo programu podano število vrednosti, pot do zbirke s podatki in število niti, ki jih želimo uporabiti za seštevanje.
|
||||
|
||||
Za odpiranje uporabite funkcijo fopen, ali pa kombinacijo open in fdopen. Nato lahko podatke preberete s funkcijo fscanf, po vzoru:
|
||||
|
||||
int val;
|
||||
fscanf(in_file_obj, "%d", &val);
|
||||
|
||||
ki prebere eno vrednost in jo hrani v spremenljivko val. V zbirki bo vsaj toliko vrednosti, kot jih potrebujete, morda več. Vrednosti preberete v dovolj veliko tabelo.
|
||||
|
||||
Nato naj glavna nit ustvari podano število niti, vsaka nit pa naj sešteje svoj del tabele. Glavna nit mora ustvariti vse niti preden začne čakati na njihove rezultate.
|
||||
|
||||
Problem seštevanja rešite s prepletanjem. Za N niti, prva nit sešteva vrednost 0, N, 2*N, ... druga nit 1, N+1, 2*N+1, ... in tako dalje (vsaka nit začne na svojem mestu tabele, nato pa skačejo po N mest).
|
||||
|
||||
Vsaka nit naj izpiše svoj delni seštevek, glavna nit pa naj nato rezultate posameznih niti sešteje in izpiše celotno vsoto.
|
||||
|
||||
Primer zagona in izpisa (prebere 11 števil iz zbirke podatki.txt in jih sešteje s 3-mi nitmi):
|
||||
|
||||
$ ./naloga_3 11 ./podatki.txt 3
|
||||
nit 1: 7
|
||||
nit 3: 5
|
||||
nit 2: 0
|
||||
vsota: 12
|
||||
|
||||
Vsebina testne zbirke podatki.txt:
|
||||
|
||||
1 -3 7 0 2 -1 4 5 -1 2 -4 1 -3 5 12 8
|
47
semester_2/uvod_v_operacijske_sisteme/naloga_05/naloga_1.c
Normal file
47
semester_2/uvod_v_operacijske_sisteme/naloga_05/naloga_1.c
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
struct thread_args{
|
||||
int post, num;
|
||||
char* mesg;
|
||||
};
|
||||
|
||||
typedef struct thread_args thread_args;
|
||||
|
||||
void* thread_main(void* args)
|
||||
{
|
||||
thread_args *object_argument = (thread_args*)args;
|
||||
|
||||
usleep(object_argument[0].num*1000);
|
||||
printf("nit %d: %s\n", object_argument[0].post, object_argument[0].mesg);
|
||||
return args;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int post = 0, value;
|
||||
thread_args args[(argc-1)/2];
|
||||
pthread_t tid[(argc-1)/2];
|
||||
|
||||
for(int i = 1; i < argc; i++)
|
||||
if(i%2 == 1)
|
||||
{
|
||||
args[post].post = post + 1;
|
||||
args[post].num = atoi (argv[i]);
|
||||
args[post].mesg = argv[i+1];
|
||||
value = pthread_create(&tid[post], NULL, thread_main, &args[post]);
|
||||
post++;
|
||||
}
|
||||
|
||||
for(int i = 0; i < post; i++)
|
||||
pthread_join(tid[i], NULL);
|
||||
|
||||
return 0;
|
||||
}
|
54
semester_2/uvod_v_operacijske_sisteme/naloga_05/naloga_2.c
Normal file
54
semester_2/uvod_v_operacijske_sisteme/naloga_05/naloga_2.c
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
struct thread_args{
|
||||
char *sporocilo;
|
||||
char mes[5];
|
||||
int pozicija;
|
||||
};
|
||||
|
||||
typedef struct thread_args thread_args;
|
||||
|
||||
void *thread_main(void *argument){
|
||||
char buffer[10];
|
||||
thread_args *object_argument = (thread_args*) argument;
|
||||
int file = open(object_argument[0].sporocilo, O_RDONLY, 0);
|
||||
read(file, buffer, sizeof(buffer));
|
||||
printf("nit %d: %s\n", object_argument[0].pozicija, buffer);
|
||||
for(int i = 0; i<10; i++){
|
||||
object_argument[0].mes[i] = buffer[i];
|
||||
}
|
||||
return argument;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int pozicija = 0;
|
||||
thread_args arg[3];
|
||||
pthread_t tid[3];
|
||||
|
||||
for(int i = 0; i<3; i++){
|
||||
arg[i].pozicija = pozicija +1;
|
||||
arg[i].sporocilo = argv[i+1];
|
||||
pthread_create(&tid[i], NULL, thread_main, &arg[i]);
|
||||
pozicija += 1;
|
||||
}
|
||||
|
||||
for(int i = 0; i<3; i++){
|
||||
pthread_join(tid[i], NULL);
|
||||
}
|
||||
|
||||
printf("\nglavna nit: ");
|
||||
for(int i = 0; i<3; i++){
|
||||
printf("%s", arg[i].mes);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
12
semester_2/uvod_v_operacijske_sisteme/naloga_06/Makefile
Normal file
12
semester_2/uvod_v_operacijske_sisteme/naloga_06/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
all: naloga_1 naloga_2 naloga_3
|
||||
naloga_1: naloga_1.c
|
||||
gcc naloga_1.c -pthread -o naloga_1
|
||||
rm naloga_1.c
|
||||
naloga_2: naloga_2.c
|
||||
gcc naloga_2.c -pthread -o naloga_2
|
||||
rm naloga_2.c
|
||||
naloga_3: naloga_3.c
|
||||
gcc naloga_3.c -pthread -o naloga_3
|
||||
rm naloga_3.c
|
||||
clean:
|
||||
rm -f naloga_1 naloga_2 naloga_3
|
55
semester_2/uvod_v_operacijske_sisteme/naloga_06/README.md
Normal file
55
semester_2/uvod_v_operacijske_sisteme/naloga_06/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
Sinhronizacija niti (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo konstruktov za sinhronizacijo iz knjižnice pthread. Pripravite 3 programe, ki izvedejo v nadaljevanju opisane naloge. Pripravite tudi Makefile, ki bo vašo kodo prevedel v izvedljive programe.
|
||||
|
||||
Za pripravo nalog je za vas pripraljena preprosta knjižnica slow.h. V njej so implementirane funkcije, ki jih morate uporabiti v rešitvah nalog 1 in 2. Knjižnico morate uporabiti kot je in jo oddati skupaj z vašimi rešitvami. Na sistemu bo zamenjana z drugo lokalno verzijo.
|
||||
|
||||
Posamezni naslovi podnalog v nadaljevanu so sestavljeni iz pričakovanega imena programa in pričakovanega imena izvorne zbirke. Na sistem oddajte .zip paket z Makefile skripto in izvornimi zbirkami. Bodite pozorni na poimenovanja. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1 (naloga_1.c)
|
||||
|
||||
Program naj ustvari dve niti. Vsaka izmed teh niti naj uporabi funkcijo pisi in trikrat izpise svojo sporočilo. Prva nit naj izpisuje sporočilo "prva\n", druga pa sporočilo "druga\n".
|
||||
|
||||
Funkcija pisi izpisuje zelo počasi, zato bi izpis dveh različnih niti lahko bil prepleten. Da se temu izognete, morate klic funkcije izvesti kot kritičen odsek kode zaščiten z mutex-om.
|
||||
naloga_2 (naloga_2.c)
|
||||
|
||||
Programu bosta podana dva argumenta. Prvi argument je celo število N, drugi pa celo število M.
|
||||
|
||||
Program naj pripravi tabelo za N celoštevilskih vrednosti in jih inicializira na 0. Pripravi in inicializira naj tudi enako veliko tabelo mutex-ov. Vsaka vrednost ima svoj mutex.
|
||||
|
||||
Nato naj ustvari M niti. Vsaka nit naj desetkrat ponovi naslednje operacije:
|
||||
|
||||
kliče funkcijo izberi_indeks s katero izbere indeks naslednjega števila
|
||||
kliče funkcijo povecaj s katerim izbrani vrednosti prišteje 1 in rezultat hrani nazaj v tabelo
|
||||
izpiše trenutno vrednost izbranega števila
|
||||
|
||||
Za opisane operacije je pomembno, da se klic funkcije izberi_indeks zgodi izven kritičnega odseka. Klic funkcije povecaj in izpis vrednosti v tabeli pa se izvede v skupnem kritičnem odseku zaščitenim z mutexom izbranega števila.
|
||||
|
||||
Glavna nit naj po zaključku vseh niti izpiše še končne vrednosti v tabeli.
|
||||
|
||||
Primeri izpisa v niti za vrednost z indeksom 3:
|
||||
|
||||
vrednost 3 je 4
|
||||
|
||||
Primer izpisa glavne niti po zaključku (za 2 niti in 5 vrednosti):
|
||||
|
||||
vrednosti: 6 8 4 1 1
|
||||
|
||||
Priložene funkcije izberi_indeks in povecaj so prilagojene tako, da vam bodo olajšale iskanje napak v sinhronizaciji. Pravilno pripravljena rešitev se bo izvedla hitro in imela pravilen izračun.
|
||||
naloga_3 (naloga_3.c)
|
||||
|
||||
Program naj ustvari 2 niti, ki bosta izmenično 2x izpisali vsaka svoje sporočilo. Prva naj izpiše "prva\n" druga pa naj izpiše "druga\n". Za izpis uporabite mutex-e in pogojne spremenljivke.
|
||||
|
||||
Preko parametrov ukazne vrstice bo podana začetna nit. V kolikor je prvi argument "prva" naj z izpisom prične prva nit. V kolikor je "druga" naj prične druga nit.
|
||||
|
||||
Primeri uporabe:
|
||||
|
||||
$ ./naloga_3 prva
|
||||
prva
|
||||
druga
|
||||
prva
|
||||
druga
|
||||
$ ./naloga_3 druga
|
||||
druga
|
||||
prva
|
||||
druga
|
||||
prva
|
33
semester_2/uvod_v_operacijske_sisteme/naloga_06/naloga_1.c
Normal file
33
semester_2/uvod_v_operacijske_sisteme/naloga_06/naloga_1.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <pthread.h>
|
||||
#include "slow.h"
|
||||
|
||||
pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void* thr_main1(){
|
||||
pthread_mutex_lock(&print_mutex);
|
||||
pisi("prva\n");
|
||||
pisi("prva\n");
|
||||
pisi("prva\n");
|
||||
pthread_mutex_unlock(&print_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* thr_main2(){
|
||||
pthread_mutex_lock(&print_mutex);
|
||||
pisi("druga\n");
|
||||
pisi("druga\n");
|
||||
pisi("druga\n");
|
||||
pthread_mutex_unlock(&print_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(){
|
||||
pthread_t tid[2];
|
||||
|
||||
pthread_create(&tid[0], NULL, thr_main1, "prva");
|
||||
pthread_create(&tid[1], NULL, thr_main2, "druga");
|
||||
|
||||
pthread_join(tid[0], NULL);
|
||||
pthread_join(tid[1], NULL);
|
||||
return 0;
|
||||
}
|
63
semester_2/uvod_v_operacijske_sisteme/naloga_06/naloga_2.c
Normal file
63
semester_2/uvod_v_operacijske_sisteme/naloga_06/naloga_2.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#include <pthread.h>
|
||||
#include "slow.h"
|
||||
|
||||
struct ThrArg {
|
||||
int max_ind;
|
||||
int *tabela;
|
||||
pthread_mutex_t *mutex;
|
||||
} typedef ThrArgd;
|
||||
|
||||
ThrArgd thr_arg;
|
||||
|
||||
void* thr_main(){
|
||||
int ret;
|
||||
for(int i = 0; i < 10; i++){
|
||||
|
||||
ret = izberi_indeks(thr_arg.max_ind);
|
||||
|
||||
pthread_mutex_lock(&thr_arg.mutex[ret]);
|
||||
|
||||
povecaj(thr_arg.tabela, ret);
|
||||
|
||||
printf("vrednost %d je %d\n", ret, thr_arg.tabela[ret]);
|
||||
|
||||
pthread_mutex_unlock(&thr_arg.mutex[ret]);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int N = atoi(argv[1]);
|
||||
int M = atoi(argv[2]);
|
||||
|
||||
|
||||
pthread_mutex_t *mutex = malloc(sizeof(pthread_mutex_t)*N);
|
||||
int *tabela = malloc(sizeof(int)*N);
|
||||
pthread_t tid[M];
|
||||
|
||||
thr_arg.tabela = tabela;
|
||||
thr_arg.mutex = mutex;
|
||||
thr_arg.max_ind = N;
|
||||
|
||||
|
||||
for(int i= 0; i<N; i++){
|
||||
pthread_mutex_init(&mutex[i],NULL);
|
||||
tabela[i] = 0;
|
||||
}
|
||||
|
||||
for(int i=0; i<M ; i++){
|
||||
pthread_create(&tid[i], NULL, thr_main, NULL);
|
||||
}
|
||||
|
||||
for(int i = 0; i<M; i++) pthread_join(tid[i],NULL);
|
||||
|
||||
printf("vrednosti:");
|
||||
for(int i = 0; i < N; i++) printf(" %d", tabela[i]);
|
||||
printf("\n");
|
||||
|
||||
free(tabela);
|
||||
free(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
52
semester_2/uvod_v_operacijske_sisteme/naloga_06/naloga_3.c
Normal file
52
semester_2/uvod_v_operacijske_sisteme/naloga_06/naloga_3.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <pthread.h>
|
||||
#include "slow.h"
|
||||
#include <string.h>
|
||||
|
||||
pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int oc = 2;
|
||||
|
||||
void* thr_main1(){
|
||||
int i = 0;
|
||||
while(i<2){
|
||||
if(oc == 1){
|
||||
printf("prva\n");
|
||||
pthread_mutex_lock(&print_mutex);
|
||||
oc = 2;
|
||||
pthread_mutex_unlock(&print_mutex);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* thr_main2(){
|
||||
int i = 0;
|
||||
while( i<2){
|
||||
if(oc == 2){
|
||||
printf("druga\n");
|
||||
pthread_mutex_lock(&print_mutex);
|
||||
oc = 1;
|
||||
pthread_mutex_unlock(&print_mutex);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
pthread_t tid[2];
|
||||
|
||||
if(strcmp("prva", argv[1]) == 0){
|
||||
oc = 1;
|
||||
}else{
|
||||
oc = 2;
|
||||
}
|
||||
|
||||
pthread_create(&tid[0], NULL, thr_main1, NULL);
|
||||
pthread_create(&tid[1], NULL, thr_main2, NULL);
|
||||
|
||||
pthread_join(tid[0], NULL);
|
||||
pthread_join(tid[1], NULL);
|
||||
return 0;
|
||||
}
|
107
semester_2/uvod_v_operacijske_sisteme/naloga_06/slow.h
Normal file
107
semester_2/uvod_v_operacijske_sisteme/naloga_06/slow.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#ifndef SLOW_H_
|
||||
#define SLOW_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
int printf_slow(const char* format, ...);
|
||||
|
||||
int pisi(const char* sporocilo){
|
||||
pthread_t tid = pthread_self();
|
||||
printf("pisi() klicana v niti %u\n", (int)tid);
|
||||
fflush(0);
|
||||
return printf_slow("%s", sporocilo);
|
||||
}
|
||||
|
||||
static pthread_mutex_t signal_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t signal_cond = PTHREAD_COND_INITIALIZER;
|
||||
int locked = 0;
|
||||
|
||||
int izberi_indeks(int max_indeks){
|
||||
struct timespec ts;
|
||||
|
||||
pthread_mutex_lock(&signal_mutex);
|
||||
if(locked==0){
|
||||
locked=1;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
ts.tv_sec += 1;
|
||||
pthread_cond_timedwait(&signal_cond, &signal_mutex, &ts);
|
||||
locked=0;
|
||||
}else{
|
||||
pthread_cond_signal(&signal_cond);
|
||||
}
|
||||
pthread_mutex_unlock(&signal_mutex);
|
||||
|
||||
int i = random()%max_indeks;
|
||||
printf("izbran indeks: %d\n", i);
|
||||
return i;
|
||||
}
|
||||
|
||||
void povecaj(int *tabela, int indeks){
|
||||
int v = tabela[indeks];
|
||||
usleep(1000);
|
||||
pthread_t tid = pthread_self();
|
||||
printf("povecaj() klicana v niti %u\n", (int)tid);
|
||||
fflush(0);
|
||||
tabela[indeks] = v+1;
|
||||
}
|
||||
|
||||
int printf_slow(const char* format, ...){
|
||||
// variable arguments list
|
||||
va_list valist;
|
||||
int ret_val;
|
||||
va_start(valist, format);
|
||||
// calculate length of formated string
|
||||
int len = vsnprintf(NULL, 0, format, valist)+1;
|
||||
va_end(valist);
|
||||
|
||||
// allocate space for formated string
|
||||
char *str = (char*)malloc(len*sizeof(char));
|
||||
|
||||
// print formated string
|
||||
va_start(valist, format);
|
||||
ret_val = vsnprintf(str, len, format, valist);
|
||||
va_end(valist);
|
||||
|
||||
// write string one byte at a time
|
||||
// with small pauses
|
||||
for(int i=0; str[i]!=0; i+=1){
|
||||
write(1, &str[i], 1);
|
||||
usleep(10);
|
||||
}
|
||||
// free the allocated space
|
||||
free(str);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
int snprintf_slow(char* str, int n, const char* format, ...){
|
||||
va_list valist;
|
||||
char *str_base = (char*)malloc(n*sizeof(char));
|
||||
memset(str_base, 0, n*sizeof(char));
|
||||
int ret_val;
|
||||
// print formated string
|
||||
va_start(valist, format);
|
||||
ret_val = vsnprintf(str_base, n, format, valist);
|
||||
va_end(valist);
|
||||
|
||||
// copy string one byte at a time
|
||||
// with small pauses
|
||||
for(int i=0; i<n; i+=1){
|
||||
str[i] = str_base[i];
|
||||
usleep(10);
|
||||
}
|
||||
// free the allocated space
|
||||
free(str_base);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
#endif //SLOW_H_
|
6
semester_2/uvod_v_operacijske_sisteme/naloga_08/Makefile
Normal file
6
semester_2/uvod_v_operacijske_sisteme/naloga_08/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
all: naloga_1 naloga_2 naloga_3
|
||||
naloga_1: naloga_1.c
|
||||
gcc naloga_1.c -pthread -lrt -o naloga_1
|
||||
rm naloga_1.c
|
||||
clean:
|
||||
rm -f naloga_1
|
@@ -0,0 +1,31 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
char *ime_cevi = "./cev_1";
|
||||
|
||||
// cev odpremo in uporabimo enako kot zbirko,
|
||||
// vendar jo moramo odpreti samo za pisanje ali samo za branje!!!
|
||||
int fd = open(ime_cevi, O_WRONLY);
|
||||
if(fd==-1){
|
||||
perror("napaka pri klicu open");
|
||||
return -1;
|
||||
}
|
||||
printf("cev uspesno odprta za pisanje \n");
|
||||
char *sporocilo = "to je malce daljse sporocilo, ki ga bomo zapisali v cev\n";
|
||||
// v cev nismo zapisali vrednosti 0 na koncu niza, na drugi strani jo moramo
|
||||
// ponovno dodati
|
||||
if(write(fd, sporocilo, strlen(sporocilo))==-1){
|
||||
perror("napaka pri klicu write");
|
||||
return -1;
|
||||
}else{
|
||||
printf("sporocilo zapisano\n");
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
char *ime_cevi = argv[1];
|
||||
|
||||
if(mkfifo(ime_cevi, S_IRUSR|S_IWUSR) == -1){
|
||||
perror("napaka pri klicu mkfifo");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fd = open(ime_cevi, O_RDONLY);
|
||||
|
||||
char sporocilo[1];
|
||||
int count = 0;
|
||||
|
||||
while(true){
|
||||
|
||||
int r = read(fd, sporocilo, 1);
|
||||
if(r==0){
|
||||
break;
|
||||
}
|
||||
if(r<0){
|
||||
perror("napaka pri klicu read");
|
||||
return -1;
|
||||
}
|
||||
printf("%s", sporocilo);
|
||||
count = count + 1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
printf("\nstevilo znakov: %d",count);
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <mqueue.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
char *ime_vrste = argv[1];
|
||||
|
||||
|
||||
|
||||
mqd_t mq_fd = mq_open(ime_vrste, O_WRONLY);
|
||||
if(mq_fd == -1){
|
||||
perror("napaka pri klicu mq_open");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *sporocilo = argv[3];
|
||||
int prioriteta = atoi(argv[2]);
|
||||
if(mq_send(mq_fd, sporocilo, strlen(sporocilo), prioriteta) == -1){
|
||||
perror("napaka pri klicu mq_send, prvic");
|
||||
}else{
|
||||
printf("sporocilo: %s, s prioriteto %d poslano\n", sporocilo, prioriteta);
|
||||
}
|
||||
|
||||
mq_close(mq_fd);
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <mqueue.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
char *ime_vrste = "/moja_vrsta";
|
||||
|
||||
// odpremo obstojeco vrsto za prejemanje sporocil
|
||||
mqd_t mq_fd = mq_open(ime_vrste, O_RDONLY);
|
||||
if(mq_fd == -1){
|
||||
perror("napaka pri klicu mq_open");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// prejmemo eno sporocilo
|
||||
char sporocilo[101]="";
|
||||
int prioriteta;
|
||||
int len = mq_receive(mq_fd, sporocilo, 100, &prioriteta);
|
||||
if(len == -1){
|
||||
perror("napaka pri klicu mq_receive");
|
||||
}else{
|
||||
sporocilo[len] = 0;
|
||||
printf("prejeto sporocilo: %s, s prioriteto %d\n", sporocilo, prioriteta);
|
||||
}
|
||||
|
||||
mq_close(mq_fd);
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <mqueue.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
char *ime_vrste = "/moja_vrsta";
|
||||
|
||||
if(mq_unlink(ime_vrste)==-1){
|
||||
perror("napaka pri klicu mq_unlink");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
|
||||
|
||||
void thread1(){
|
||||
|
||||
ce nisi dobil error{
|
||||
cv = odpri cev2 WRONLY
|
||||
}ce si dobil error{
|
||||
cv = odpri cev1 WRONLY
|
||||
}
|
||||
|
||||
while(running){
|
||||
preberi sporocilo iz terminala;
|
||||
ce je sporocilo enako ""{
|
||||
poslji v cv ("n");
|
||||
zaustavi thread1(brak)
|
||||
!!!uporabi pthread_cancel() da ustavis thread2!!!
|
||||
}ce ne{
|
||||
poslji v cv (sporocilo);
|
||||
}
|
||||
}
|
||||
zapri cv;
|
||||
}
|
||||
|
||||
void thread2(){
|
||||
|
||||
ce nisi dobil error{
|
||||
cv = odpri cev1 RDONLY
|
||||
}ce si dobil error{
|
||||
cv = odpri cev2 RDONLY
|
||||
}
|
||||
|
||||
while(running){
|
||||
preberi iz cevi (cv) sporocilo;
|
||||
|
||||
izpisi na terminal sporocilo;
|
||||
|
||||
ce je sporocilo enako "n"{
|
||||
zaustavi thread2(brak)
|
||||
!!!uporabi pthread_cancel() da ustavis thread1!!!
|
||||
}
|
||||
}
|
||||
|
||||
zapri cv;
|
||||
}
|
||||
|
||||
|
||||
main(){
|
||||
char cev1 = "./" + argv[1] + "1";
|
||||
char cev2 = "./" + argv[1] + "2";
|
||||
|
||||
ustvari cev1;
|
||||
ustvari cev2;
|
||||
ce dobis error da cev obstaja si zapomni;
|
||||
|
||||
ustvari thread 1 in 2;
|
||||
|
||||
pocakaj da se thred 1 in 2 zakljuci;
|
||||
|
||||
unlink cev 1 in 2;
|
||||
}
|
||||
|
||||
|
||||
za prenos podatkov med cevmi in thredi je meni bilo najlazje uporabljati globalne premenljivke
|
40
semester_2/uvod_v_operacijske_sisteme/naloga_08/README.md
Normal file
40
semester_2/uvod_v_operacijske_sisteme/naloga_08/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
Medprocesna komunikacija (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo metod za medprocesno komunikacijo. Pripravite 3 programe, ki izvedejo v nadaljevanju opisane naloge. Pripravite tudi Makefile, ki bo vašo kodo prevedel v izvedljive programe.
|
||||
|
||||
Posamezni naslovi podnalog v nadaljevanu so sestavljeni iz pričakovanega imena programa in pričakovanega imena izvorne zbirke. Na sistem oddajte .zip paket z Makefile skripto in izvornimi zbirkami. Bodite pozorni na poimenovanja. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1 (naloga_1.c)
|
||||
|
||||
Program naj ustvari cev, pot z imenom bo podana v prvem argumentu. Če podana pot kaže na že obstoječo zbirko, kazalo ali cev naj izpiše sporočilo. Nato naj program prebere vsebino in prešteje število vseh poslanih znakov. Po zaključku branja naj izpiše prešteto število poslanih znakov.
|
||||
|
||||
Primer zagona:
|
||||
|
||||
$ ./naloga_1 ./nova_cev &
|
||||
$ ( echo -n "pozdravljen "; sleep 1; echo svet ) > ./nova_cev # to lahko pozenete tudi v drugem terminalu v isti poti, spodnji izpis je od programa ./naloga_1
|
||||
stevilo znakov: 17
|
||||
|
||||
naloga_2 (naloga_2.c)
|
||||
|
||||
Program prejme tri argumente. Prvi argument je ime vrste za sporočila, drugi argument je prioriteta sporočila, tretji argument pa sporočilo. Program naj odpre vrsto za sporočila in pošlje podano sporočilo s podano prioriteto. V kolikor pride to težav, naj izpiše primerno opozorilo.
|
||||
|
||||
Primer zagona:
|
||||
|
||||
$ ./naloga_2 /nova_vrsta 1 hello
|
||||
$ ./naloga_2 /nova_vrsta 1 world
|
||||
$ ./naloga_2 /nova_vrsta 1 ""
|
||||
$ ./naloga_2 /nova_vrsta 1 "hello world"
|
||||
napaka pri odpiranju vrste, vrsta ne obstaja
|
||||
|
||||
naloga_3 (naloga_3.c)
|
||||
|
||||
Napišite program, ki bo omogočal dvosmerno komunikacijo. Kot prvi argument naj program prejme ključ (ključ bo veljavno ime zbirke ali vrste za sporočila brez začetnega '/'). V kolikor program poženete dvakrat iz različnih terminalov z istim ključem, si oba pognana programa pošiljata sporočila med sabo. Programa pognana z različnima ključema ne omogočata komunikacije.
|
||||
|
||||
Za komunikacijo lahko uporabite cevi ali vrste za sporočila. V obeh primerih boste potrebovali dva primerka. Prva cev ali vrsta pošilja sporočila od prvega programa drugemu, druga cev ali vrsta pošilja sporočila od drugega programa prvemu. Dobro premislite o vaši izbiri, ena je morda primernejša in enostavnejša za uporabo.
|
||||
|
||||
Iz podanega ključa naj program ustvari dva različna imena in z njima poskusi ustvariti dve cevi ali vrsti za sporočila. V kolikor jih uspešno ustvari, je to prva pognana instanca. V kolikor cevi ali vrsti že obstajajo, je to druga pognana instanca.
|
||||
|
||||
Program naj bere sporočila z standardnega vhoda dolga vsaj 10 znakov. Vsako prebrano sporočilo naj pošlje drugemu programu. Vsako prejeto sporočilo naj izpiše na standardni izhod. Komunikacija ni nujno izmenična. Program se zaključi kadar prejme prazno sporočilo (samo "n"). Ob zaključku enega programa se zaključi tudi drugi. Cevi ali vrsti uporabljeni za komunikacijo je potrebno pred zaključkom programov pobrisati, da lahko ponovno poženemo dve istanci z istim ključem.
|
||||
|
||||
Primer zagona (samo za podan argument, dejanska uporaba in pošiljanje nista prikazana):
|
||||
|
||||
$ ./naloga_3 kljuc_1234
|
121
semester_2/uvod_v_operacijske_sisteme/naloga_08/naloga_3.c
Normal file
121
semester_2/uvod_v_operacijske_sisteme/naloga_08/naloga_3.c
Normal file
@@ -0,0 +1,121 @@
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
char cev1[100] = "./";
|
||||
char cev2[100] = "./";
|
||||
int running = 1;
|
||||
int icev1, icev2;
|
||||
pthread_t tid[2];
|
||||
|
||||
void* thrpisi(){
|
||||
char sporocilo[10];
|
||||
int closep = 0;
|
||||
while(running == 1){
|
||||
//if (scanf( "%10s", sporocilo ) == 0) break;
|
||||
|
||||
int c;
|
||||
size_t i = 0;
|
||||
while (i < 9 && (c=getchar()) != EOF) {
|
||||
sporocilo[i] = c;
|
||||
if (sporocilo[i] == '\n') {
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
sporocilo[i] = '\0';
|
||||
|
||||
printf("poslali smo: %s\n", sporocilo);
|
||||
if(strcmp(sporocilo, "") == 0){
|
||||
write(icev1, "n", strlen("n"));
|
||||
printf("se ujema\n");
|
||||
running = 0;
|
||||
pthread_cancel(tid[1]);
|
||||
break;
|
||||
}
|
||||
write(icev1, sporocilo, strlen(sporocilo));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* thrberi(){
|
||||
char sporocilo[10];
|
||||
int l;
|
||||
int closep = 0;
|
||||
while(running == 1){
|
||||
l = read(icev2, sporocilo, sizeof(sporocilo));
|
||||
if(l<=0)break;
|
||||
sporocilo[l] = 0;
|
||||
printf("prejeli smo odgovor: %s\n",sporocilo);
|
||||
if(strcmp(sporocilo, "n") == 0){
|
||||
printf("se ujema\n");
|
||||
running = 0;
|
||||
pthread_cancel(tid[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
char* src = argv[1];
|
||||
|
||||
|
||||
strcat(cev1, src);
|
||||
strcat(cev1, "vhod");
|
||||
printf("%s\n", cev1);
|
||||
|
||||
strcat(cev2,src);
|
||||
strcat(cev2,"izhod");
|
||||
printf("%s\n", cev2);
|
||||
|
||||
int created = 0;
|
||||
if(mkfifo(cev1, S_IRUSR|S_IWUSR)==-1){
|
||||
perror("napaka pri klicu mkfifo");
|
||||
}
|
||||
|
||||
if(mkfifo(cev2, S_IRUSR|S_IWUSR)==-1){
|
||||
perror("napaka pri klicu mkfifo");
|
||||
}
|
||||
|
||||
if(mkfifo("test", S_IRUSR|S_IWUSR)==-1){
|
||||
created = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(created){
|
||||
icev1 = open(cev1, O_WRONLY);
|
||||
icev2 = open(cev2, O_RDONLY);
|
||||
|
||||
}else{
|
||||
icev2 = open(cev1, O_RDONLY);
|
||||
icev1 = open(cev2, O_WRONLY);
|
||||
}
|
||||
|
||||
pthread_create(&tid[0], NULL, thrpisi, NULL);
|
||||
pthread_create(&tid[1], NULL, thrberi, NULL);
|
||||
|
||||
pthread_join(tid[0], NULL);
|
||||
pthread_join(tid[1], NULL);
|
||||
|
||||
close(icev1);
|
||||
close(icev2);
|
||||
|
||||
printf("closing\n");
|
||||
unlink(cev1);
|
||||
unlink(cev2);
|
||||
unlink("test");
|
||||
return 0;
|
||||
}
|
||||
|
17
semester_2/uvod_v_operacijske_sisteme/naloga_09/Makefile
Normal file
17
semester_2/uvod_v_operacijske_sisteme/naloga_09/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
all: naloga_1 naloga_2 naloga_3
|
||||
|
||||
naloga_1: naloga_1.c
|
||||
gcc naloga_1.c -o naloga_1
|
||||
|
||||
naloga_2: naloga_2.c
|
||||
gcc naloga_2.c -o naloga_2
|
||||
|
||||
naloga_3: naloga_3.c
|
||||
gcc naloga_3.c -o naloga_3
|
||||
|
||||
zip:
|
||||
rm -f naloga.zip
|
||||
zip -r naloga.zip ./
|
||||
|
||||
clean:
|
||||
rm -f naloga_1 naloga_2 naloga_3
|
48
semester_2/uvod_v_operacijske_sisteme/naloga_09/README.md
Normal file
48
semester_2/uvod_v_operacijske_sisteme/naloga_09/README.md
Normal file
@@ -0,0 +1,48 @@
|
||||
Ustvarjanje procesa (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo klicev za ustvarjanje procesov in zaganjanje programov. Pripravite 3 programe, ki izvedejo v nadaljevanju opisane naloge. Pripravite tudi Makefile, ki bo vašo kodo prevedel v izvedljive programe.
|
||||
|
||||
Posamezni naslovi podnalog v nadaljevanu so sestavljeni iz pričakovanega imena programa in pričakovanega imena izvorne zbirke. Na sistem oddajte .zip paket z Makefile skripto in izvornimi zbirkami. Bodite pozorni na poimenovanja. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1 (naloga_1.c)
|
||||
|
||||
Program naj ustvari 5 novih procesov, otrok. Vsak otrok naj izpiše svoj PID in PID starša. Starš naj počaka, da se otroci zaključijo in nato izpiše svoj PID. Otroci naj se izvajajo vzporedno (kolikor bo sistem to dopuščal). Starš najprej ustvari vse otroke, šele nato jih prične čakati.
|
||||
|
||||
Primer zagona:
|
||||
|
||||
$ ./naloga_1
|
||||
otrok PID: 1324758, PPID: 1324757
|
||||
otrok PID: 1324759, PPID: 1324757
|
||||
otrok PID: 1324760, PPID: 1324757
|
||||
otrok PID: 1324761, PPID: 1324757
|
||||
otrok PID: 1324762, PPID: 1324757
|
||||
stars PID: 1324757
|
||||
|
||||
naloga_2 (naloga_2.c)
|
||||
|
||||
Program bo prejel dva argumenta. Prvi argument bo pot do vhodne zbirke, drugi argument bo pot do izhodne zbirke. Vhodna zbirka mora obstajati, izhodna ne sme. Program naj odpre zbirki in svoj standardni vhod zamenja z vhodno zbirko, svoj standardni izhod pa z izhodno zbirko. Nato naj požene program tr (klic fork ni potreben) s parametri "a-z" in "A-Z" kot:
|
||||
|
||||
$ tr a-z A-Z
|
||||
|
||||
to bo zamenjalo vse male črke vhodne zbirke z velikimi črkami in jih zapisalo v izhodno zbirko.
|
||||
|
||||
Primer zagona in izhoda:
|
||||
|
||||
$ echo hello world > vhod.txt
|
||||
$ ./naloga_2 vhod.txt izhod.txt
|
||||
$ cat izhod.txt
|
||||
HELLO WORLD
|
||||
$ ./naloga_2 vhod.txt izhod.txt
|
||||
napaka pri klicu open: file exists
|
||||
|
||||
naloga_3 (naloga_3.c)
|
||||
|
||||
Program bo preko argumentov prejel pot do programa in njegove parametre. Vaš program naj ustvari nov proces in v tem procesu požene podan program. Vaš program naj počaka da se podan program zaključi, nato pa naj prebere in izpiše njegovo izhodno vrednost. V primeru, da pri izvajanju podanega programa pride do napake, naj vaš program izpiše primerno opozorilo in izhodno vrednost -1.
|
||||
|
||||
Primer zagona:
|
||||
|
||||
$ ./naloga_3 /usr/bin/echo hello world
|
||||
hello world
|
||||
program je vrnil vrednost 0
|
||||
$ ./naloga_3 /usr/bin/ls ne_obstaja/
|
||||
/usr/bin/ls: cannot access 'ne_obstaja/': No such file or directory
|
||||
program je vrnil vrednost 2
|
26
semester_2/uvod_v_operacijske_sisteme/naloga_09/naloga_1.c
Normal file
26
semester_2/uvod_v_operacijske_sisteme/naloga_09/naloga_1.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
pid_t pid;
|
||||
|
||||
for (int i = 0; i < 5; i++){
|
||||
pid = fork();
|
||||
if(pid == 0){
|
||||
printf("PID: %d, PPID: %d\n", getpid(), getppid());
|
||||
exit(pid);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
wait(NULL);
|
||||
}
|
||||
|
||||
printf("PID: %d\n", getpid());
|
||||
|
||||
return 0;
|
||||
}
|
30
semester_2/uvod_v_operacijske_sisteme/naloga_09/naloga_2.c
Normal file
30
semester_2/uvod_v_operacijske_sisteme/naloga_09/naloga_2.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
int in = open(argv[1], O_RDONLY);
|
||||
if(in == -1){
|
||||
perror("file doesn't exist\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(access(argv[2], F_OK) == 0)
|
||||
return -1;
|
||||
|
||||
int out = open(argv[2], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
|
||||
dup2(in, STDIN_FILENO);
|
||||
dup2(out, STDOUT_FILENO);
|
||||
|
||||
close(in);
|
||||
close(out);
|
||||
|
||||
char* arg[] = {"tr", "a-z", "A-Z", 0};
|
||||
execvp(arg[0], arg);
|
||||
|
||||
return 0;
|
||||
}
|
55
semester_2/uvod_v_operacijske_sisteme/naloga_09/naloga_3.c
Normal file
55
semester_2/uvod_v_operacijske_sisteme/naloga_09/naloga_3.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv){
|
||||
|
||||
char* args[argc]; //argc == amount of arguments
|
||||
for(int i = 0; i < argc; i++){
|
||||
args[i] = argv[i+1];
|
||||
}
|
||||
args[argc-1] = 0;
|
||||
|
||||
int exit_status;
|
||||
|
||||
int new_pid = fork();
|
||||
|
||||
// po klicu fork imat stars in otrok oba oprimka do iste cevi,
|
||||
// in lahko v njo piseta ali iz nje bereta
|
||||
switch(new_pid){
|
||||
int ret_val;
|
||||
case -1:
|
||||
perror("napaka pri klicu fork");
|
||||
break;
|
||||
case 0:
|
||||
ret_val = execvp(args[0], args);
|
||||
if(ret_val == -1){
|
||||
perror("napaka pri klicu exec");
|
||||
}
|
||||
exit(ret_val); // proces se tukaj zakljuci
|
||||
break;
|
||||
default:
|
||||
// z dodatnim argumentom wait ali waitpid lahko
|
||||
// preberemo vrednost, ki jo proces vrne ob zakljucku
|
||||
waitpid(new_pid, &exit_status, 0);
|
||||
}
|
||||
|
||||
// preverimo, ali je proces vrnil vrednost
|
||||
if(WIFEXITED(exit_status)){
|
||||
int r = WEXITSTATUS(exit_status);
|
||||
if(r == 255) r = -1;
|
||||
printf("program je vrnil vrednost %d\n", r);
|
||||
}
|
||||
// preverimo, ali je proces bil prekinjen z signalom, na primer SegFault
|
||||
if(WIFSIGNALED(exit_status)){
|
||||
int sig_ind = WTERMSIG(exit_status);
|
||||
printf("program se je zakljucil s signalom %s\n", strsignal(sig_ind));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
29
semester_2/uvod_v_operacijske_sisteme/naloga_10/Makefile
Normal file
29
semester_2/uvod_v_operacijske_sisteme/naloga_10/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
all: naloga_1 naloga_2
|
||||
|
||||
naloga_1:
|
||||
gcc naloga_1.c -o naloga_1
|
||||
|
||||
naloga_2:
|
||||
gcc naloga_2.c -o naloga_2
|
||||
|
||||
naloga_3:
|
||||
gcc naloga_3.c -o naloga_3
|
||||
|
||||
zip:
|
||||
rm -f naloga_1 naloga_2 naloga.zip
|
||||
zip naloga.zip naloga_1.c naloga_2.c Makefile
|
||||
|
||||
test1:
|
||||
gcc naloga_1.c -o naloga_1
|
||||
echo -n 'abcd' | ./naloga_1
|
||||
|
||||
test2:
|
||||
gcc naloga_2.c -o naloga_2
|
||||
echo 3 4 -5 2 4 3 2 11 | ./naloga_2
|
||||
|
||||
test3:
|
||||
gcc naloga_3.c -o naloga_3
|
||||
./naloga_3
|
||||
|
||||
clean:
|
||||
rm -f naloga_1 naloga_2 naloga_3
|
106
semester_2/uvod_v_operacijske_sisteme/naloga_10/README.md
Normal file
106
semester_2/uvod_v_operacijske_sisteme/naloga_10/README.md
Normal file
@@ -0,0 +1,106 @@
|
||||
Manipulacija pomnilnika (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo kazalcev in struktur za interpretacijo in manipulacijo podatkov neobičajnih oblik. Pripravite 3 rešitve (2 programa in eno implementacijo funkcije) v nadaljevanju opisanih nalog. Pripravite tudi Makefile, ki bo vašo kodo prevedel v izvedljive programe.
|
||||
|
||||
Posamezni naslovi podnalog v nadaljevanu so sestavljeni iz pričakovanega imena programa in pričakovanega imena izvorne zbirke. Na sistem oddajte .zip paket z Makefile skripto in izvornimi zbirkami. Bodite pozorni na poimenovanja. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1 (naloga_1.c)
|
||||
|
||||
Program naj s standardnega vhoda bere racionalna števila (ulomke) v nadaljevanju opisani obliki. Na standardni izhod naj izpisuje ulomke v berljivi obliki <števec>/<imenovalec>. Primer izpisa programa:
|
||||
|
||||
3/4 -1/2 6/14
|
||||
|
||||
Racionalna števila bodo zapisana v posameznih zlogih/bajtih. Vsak zlog bo razdeljen na dva dela. Pomembnejši štirje biti (vrednosti 128, 64, 32 in 16) bodo vsebovali števec ulomka, zapisan kot predznačeno celo število (vrednosti med -8 in 7). Manj pomembni štirje biti (vrednosti 8, 4, 2 in 1) bodo vsebovali imenovalec ulomka, zapisan kot nepredznačeno celo število (vrednosti med 0 in 15).
|
||||
|
||||
Biti v enem zlogu predstavljajo posamezne vrednost. Naslednja tabela prikazuje nekaj primerov:
|
||||
vrednost bitna predstava
|
||||
a b c d e f g h
|
||||
128 1 0 0 0 0 0 0 0
|
||||
64 0 1 0 0 0 0 0 0
|
||||
32 0 0 1 0 0 0 0 0
|
||||
16 0 0 0 1 0 0 0 0
|
||||
8 0 0 0 0 1 0 0 0
|
||||
4 0 0 0 0 0 1 0 0
|
||||
2 0 0 0 0 0 0 1 0
|
||||
1 0 0 0 0 0 0 0 1
|
||||
71=64+4+2+1 0 1 0 0 0 1 1 1
|
||||
255=... 1 1 1 1 1 1 1 1
|
||||
|
||||
Vrednost 128 je v enem zlogu predstavljena z zadnjim bitom a, ki ga smatramo tudi kot najpomemnejši ker predstavlja največjo vrednost. Vrednost 2 pa je predstavljena z 2 bitom g. Ostala nepredznačena cela števila so predstavljena s kombinacijo bitov oziroma seštevkom njihovih vrednosti. Število 71 je tako predstavljeno z zlogom 01000111, oziroma seštevkom 64+4+2+1. Število 255 je kombinacija vseh bitov.
|
||||
|
||||
Po zgornjem opisu želimo v bite a b c d zapisati števec, v bite e f g h pa imenovalec.
|
||||
|
||||
Iz standardnega vhoda mora prebrati vse podane zloge.
|
||||
naloga_2 (naloga_2.c)
|
||||
|
||||
Program naj iz standardnega vhoda bere pare vrednosti - števce in imenovalce ulomkov. Na standardni izhod naj izpiše racionalna števila v obliki opisani za naloga_1. Program naj bo kompatibilen z naloga_1.
|
||||
|
||||
Za branje lahko uporabite funkcijo scanf. Z njo lahko preberete posamezno število s klicem:
|
||||
|
||||
int v;
|
||||
scanf("%d", &v);
|
||||
|
||||
Primer zagona (v kombinaciji z naloga_1):
|
||||
|
||||
$ echo -n 3 4 -1 2 6 14 | ./naloga_2 | ./naloga_1
|
||||
3/4 -1/2 6/14
|
||||
|
||||
Velikost izhoda mora biti kot predpisana. V zgornjem primeru, kjer so podani 3 pari imenovalcev in števcev mora izhod biti velik 3 zloge/bajte.
|
||||
naloga_3.h
|
||||
|
||||
V tej nalogi implementirajte funkcijo v zaglavju naloga_3.h.
|
||||
|
||||
Implementirajte funkcijo split, ki C niz razreže na podnize ločene z izbranim znakom. Funkcija naj ima naslednji podpis:
|
||||
|
||||
char** split(const char* str, char delim, int *n);
|
||||
|
||||
Kjer je str niz, ki ga želimo razrezati, delim je znak s katerim nize razrežemo, n pa je kazalec na celo število, kamor bomo zapisali število najdenih nizov. Funkcija vrne kazalec na tabelo razrezanih podnizov. Vrnjena tabela je dinamično alocirana in jo sprostimo z enim klicem free. Vaša implementacija bo preizkušena z naslednjim programom, drugačnimi parametri:
|
||||
|
||||
#include <stdio.h>
|
||||
#include "naloga_3.h"
|
||||
|
||||
int main(){
|
||||
int n=0;
|
||||
char *str="hello world !!!";
|
||||
char delim=' ';
|
||||
printf("vhodni niz: %s\n", str);
|
||||
printf("separator: %c\n", delim);
|
||||
|
||||
char **besede = split(str, delim, &n);
|
||||
printf("besede:\n");
|
||||
for(int i=0; i<n; i+=1){
|
||||
printf("%s\n", besede[i]);
|
||||
}
|
||||
free(besede);
|
||||
}
|
||||
|
||||
Primer bi naj izpisal:
|
||||
|
||||
vhodni niz: hello world !!!
|
||||
separator:
|
||||
besede:
|
||||
hello
|
||||
world
|
||||
!!!
|
||||
|
||||
Predlagamo naslednjo implementacijo (možne so razlike v implementaciji, dokler je izpolnjen zgoraj opisan način uporabe).
|
||||
|
||||
Najprej preštejte število ponovitev simbola delim v podanem nizu str. To število povečate za 1 in shranite na lokacijo kazalca n (število podnizov je 1 več kot število pojavitev simbola).
|
||||
|
||||
Nato alocirajte pomnilnik, ki bo lahko vseboval tabelo n-tih kazalcev char* in celotno dolžino podanega niza (to morate opraviti z enkratnim klicem malloc za katerega uporabnik nato kliče free). Na začetek tega pomnilnika shranite tabelo kazalcev char* (tabela je tipa char**). Na konec te tabele pa shranite kopijo niza.
|
||||
|
||||
Prvi kazalec v tabeli incializirate tako, da kaže na začetek kopije niza. Nato se sprehodite skozi znake kopije. Kjer najdete simbol delim ga zamenjate z simbolom '0' (tako zaključite prejšnji odsek kopije). Naslednji kazalec v tabeli nastavite na naslov za zamenjanim elementom.
|
||||
|
||||
Primer zapisa v pomnilniku na sistemu, kjer je kazalec velik 1 zlog/bajt in malloc vrne dinamično alociran pomnilnik na naslovu 10:
|
||||
naslov 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
||||
znak h e l l o w o r l d ! ! !
|
||||
vrednost 13 19 25 0 0 0
|
||||
|
||||
V prvi vrstici so zapisani naslovi v pomnilniku v desetiški obliki. Ti se pričnejo z 10, potrebujemo jih 19.
|
||||
|
||||
V drugi vrstici so zapisani znaki zapisanih vrednosti, če jih interpretiramo kot tip char. Ti so zapisani samo na mestih, kjer jih želimo interpretirati kot znake.
|
||||
|
||||
V tretji vrstici so zapisane številske vrednosti zapisanih bajtov v desetiški obliki.
|
||||
|
||||
Kjer so v 2 vrstici zapisani znaki, v 3 vrstici niso zapisane njihove številske vrednost. Znaki imajo številske vrednosti, ampak ker nas v tem primeru ne zanimajo, so iz jasnosti izpuščene.
|
||||
|
||||
Za ta primer bi funkcija vrnila naslov 10 kot tip char**.
|
19
semester_2/uvod_v_operacijske_sisteme/naloga_10/naloga_1.c
Normal file
19
semester_2/uvod_v_operacijske_sisteme/naloga_10/naloga_1.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct {
|
||||
unsigned short val_1 : 4;
|
||||
int val_2 : 4;
|
||||
} typedef myStructBitField;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
myStructBitField c;
|
||||
|
||||
while(read(0,&c,1) > 0){
|
||||
printf("%d/%d ", c.val_2,c.val_1);
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
20
semester_2/uvod_v_operacijske_sisteme/naloga_10/naloga_2.c
Normal file
20
semester_2/uvod_v_operacijske_sisteme/naloga_10/naloga_2.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct {
|
||||
unsigned int val_2 : 4;
|
||||
int val_1 : 4;
|
||||
} typedef myStructBitField;
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
myStructBitField nik;
|
||||
int stevilo1, stevilo2;
|
||||
while(scanf("%d%d", &stevilo1, &stevilo2) > 0){
|
||||
nik.val_1 = stevilo1;
|
||||
nik.val_2 = stevilo2;
|
||||
write(1,&nik,1);
|
||||
}
|
||||
return 0;
|
||||
}
|
10
semester_2/uvod_v_operacijske_sisteme/naloga_11/Makefile
Normal file
10
semester_2/uvod_v_operacijske_sisteme/naloga_11/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
all: naloga_1
|
||||
|
||||
naloga_1: naloga_1.c
|
||||
gcc naloga_1.c -o naloga_1
|
||||
|
||||
clean:
|
||||
rm -f naloga_1 naloga_2 naloga_3 naloga.zip
|
||||
|
||||
zip: clean
|
||||
zip naloga.zip Makefile naloga_1.c naloga_2.c
|
29
semester_2/uvod_v_operacijske_sisteme/naloga_11/README.md
Normal file
29
semester_2/uvod_v_operacijske_sisteme/naloga_11/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
Semafor (sprotna naloga)
|
||||
|
||||
V sklopu te naloge demonstrirajte uporabo semaforja POSIX. Pripravite 3 programe, ki izvedejo v nadaljevanju opisane naloge. Pripravite tudi Makefile, ki bo vašo kodo prevedel v izvedljive programe.
|
||||
|
||||
Posamezni naslovi podnaloge v nadaljevanu so sestavljeni iz pričakovanega imena programa in pričakovanega imena izvorne zbirke.
|
||||
|
||||
Na sistem oddajte .zip paket z Makefile skripto in izvornimi zbirkami. Bodite pozorni na poimenovanja. Pred oddajo preverite delovanje z avtomatskim preizkusom.
|
||||
naloga_1 (naloga_1.c)
|
||||
|
||||
Vaš program bo prejel parametre preko ukazne vrstice v obliki:
|
||||
|
||||
$ ./naloga_1 <ime> <+1,-1>
|
||||
|
||||
Prvi parameter je ime semaforja, ki ga program odpre. V kolikor semafor s tem imenom ne obstaja, naj program izpiše ustrezno sporočilo. Drugi parameter je lahko +1. Takrat naj vaš program poveča vrednost semaforja za 1. Drugi parameter je lahko tudi -1. Takrat naj vaš program zmanjša vrednost semaforja za 1 (program seveda čaka, če je vrednost semaforja 0).
|
||||
|
||||
Po uspešno izvedeni operaciji naj program izpiše sporočilo, iz katerega bo jasno ali je zmanjšal ali zvečal vrednost semaforja.
|
||||
naloga_2 (naloga_2.c)
|
||||
|
||||
Vaš program bo prejel parametre preko ukazne vrstice v obliki:
|
||||
|
||||
$ ./naloga_2 <ime> <dolzina>
|
||||
|
||||
Program ustvari deljen pomnilnik s podanim imenom. Pomnilnik mora biti dovolj velik, da bo lahko vseboval dva semaforja in niz znakov podane dožine (dolžina je celo število podano kot drug parameter programa).
|
||||
|
||||
Program naj na začetku pomnilnika inicializira dva semaforja. Prvi semafor, ki nadzira branje sporočila, naj bo inicializiran na 0. Drugi semafor, ki nadzira pisanje sporočila, naj bo inicializiran na 1.
|
||||
|
||||
Program naj nato v zanki čaka na zapisana sporočila. Najprej naj zmanjša vrednost na prvem semaforju. Tu program čaka na prejeto sporočilo. Ob prejemu, sporočilo izpiše na standardni izhod. Nato zveča vrednost drugega semaforja in tako omogoči zapis naslednjega sporočila.
|
||||
|
||||
Ob prejemu praznega sporočila (dolžina niza je 0) progam izbriše oba semaforja in deljen pomnilnik ter se zaključi.
|
42
semester_2/uvod_v_operacijske_sisteme/naloga_11/naloga_1.c
Normal file
42
semester_2/uvod_v_operacijske_sisteme/naloga_11/naloga_1.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int fd = open(argv[1], O_RDONLY);
|
||||
if(fd == -1){
|
||||
perror("napaka pri klicu open");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct stat fd_stat;
|
||||
if(fstat(fd,&fd_stat)==-1)
|
||||
{
|
||||
perror("tezava pri branju statistike zbirke");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *besedilo_mmap = mmap(0, fd_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if(besedilo_mmap == MAP_FAILED)
|
||||
{
|
||||
perror("tezava pri preslikavi pomnilnika");
|
||||
}
|
||||
close(fd);
|
||||
|
||||
|
||||
for (int i = 0; i < fd_stat.st_size; i++)
|
||||
{
|
||||
printf("%.2hhx ", besedilo_mmap[i]);
|
||||
if (i % 8 == 7)
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user