Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Dong Hung Pham
Betriebssystem Mi2X
Commits
2e779f1a
Commit
2e779f1a
authored
Jan 19, 2021
by
Dong Hung Pham
🤡
Browse files
Add new file prak4 mit semaphore
parent
f594fee1
Changes
1
Hide whitespace changes
Inline
Side-by-side
prak4NEW.cpp
0 → 100644
View file @
2e779f1a
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
#include <time.h>
#include <semaphore.h>
#include <chrono>
#include <iostream>
#include <fstream>
#include <unistd.h>
using
namespace
std
;
pthread_mutex_t
mutex
=
PTHREAD_MUTEX_INITIALIZER
;
int
m
,
n
,
r
,
k
,
t
;
int
sumDoener
=
0
;
sem_t
semaphoreVerkaufer
;
// wenn es mindest eine freie Verkaufer gibt , darf die Kunden bestellen
sem_t
semaphoreKundenReihe
;
//um zu kontrollieren , die genaue reihe von Kunden werden bestellen , vermeiden race condition
sem_t
sem0
;
sem_t
sem1
;
sem_t
sem2
;
sem_t
sem3
;
sem_t
sem4
;
sem_t
sem5
;
sem_t
sem6
;
sem_t
sem7
;
std
::
vector
<
sem_t
>
listSem
;
pthread_mutex_t
Sauce
=
PTHREAD_MUTEX_INITIALIZER
;
pthread_mutex_t
Brot
=
PTHREAD_MUTEX_INITIALIZER
;
pthread_mutex_t
Salat
=
PTHREAD_MUTEX_INITIALIZER
;
pthread_mutex_t
Fleisch
=
PTHREAD_MUTEX_INITIALIZER
;
int
nSauce
,
nBrot
,
nSalat
,
nFleisch
;
bool
nichtFertig
=
true
;
std
::
vector
<
bool
>
vectorCondition
;
std
::
vector
<
std
::
vector
<
int
>>
vectorKundenBestellung
;
std
::
vector
<
pthread_mutex_t
>
listMutexVerkaufen
;
std
::
vector
<
pthread_mutex_t
>
listMutexMakeDoner
;
void
*
refill
(
void
*
time
){
int
wait
=
((
long
)
time
)
*
t
;
printf
(
"refill in %ld second
\n
"
,(
long
)
time
);
usleep
(
wait
);
pthread_exit
(
NULL
);
}
void
getSauce
(
int
anzahl
,
int
time
){
pthread_mutex_lock
(
&
Sauce
);
int
count
=
0
;
while
(
count
!=
anzahl
)
{
//printf("make a sauce \n");
if
(
nSauce
==
0
){
//printf("need refill sauce \n");
long
rate
=
n
/
r
;
pthread_t
refillThread
;
int
status
=
pthread_create
(
&
refillThread
,
NULL
,
refill
,(
void
*
)
rate
);
pthread_join
(
refillThread
,
NULL
);
nSauce
=
n
;
}
count
++
;
usleep
(
time
);
nSauce
--
;
}
printf
(
"fertig sauce
\n
"
);
pthread_mutex_unlock
(
&
Sauce
);
}
void
getBrot
(
int
anzahl
,
int
time
){
pthread_mutex_lock
(
&
Brot
);
int
count
=
0
;
while
(
count
!=
anzahl
)
{
//printf("make a brot \n");
if
(
nBrot
==
0
){
//printf("need refill brot \n");
long
rate
=
n
/
r
;
pthread_t
refillThread
;
int
status
=
pthread_create
(
&
refillThread
,
NULL
,
refill
,(
void
*
)
rate
);
pthread_join
(
refillThread
,
NULL
);
nBrot
=
n
;
}
count
++
;
usleep
(
time
);
nBrot
--
;
}
printf
(
"fertig brot
\n
"
);
pthread_mutex_unlock
(
&
Brot
);
}
void
getSalat
(
int
anzahl
,
int
time
){
pthread_mutex_lock
(
&
Salat
);
int
count
=
0
;
while
(
count
!=
anzahl
)
{
//printf("make a salat \n");
if
(
nSalat
==
0
){
//printf("need refill salat \n");
long
rate
=
n
/
r
;
pthread_t
refillThread
;
int
status
=
pthread_create
(
&
refillThread
,
NULL
,
refill
,(
void
*
)
rate
);
pthread_join
(
refillThread
,
NULL
);
nSalat
=
n
;
}
count
++
;
usleep
(
time
);
nSalat
--
;
}
printf
(
"fertig salat
\n
"
);
pthread_mutex_unlock
(
&
Salat
);
}
void
getFleisch
(
int
anzahl
,
int
time
){
pthread_mutex_lock
(
&
Fleisch
);
int
count
=
0
;
while
(
count
!=
anzahl
)
{
// printf("make a ffleisch \n");
if
(
nFleisch
==
0
){
//printf("need refill fleisch \n");
long
rate
=
n
/
r
;
pthread_t
refillThread
;
int
status
=
pthread_create
(
&
refillThread
,
NULL
,
refill
,(
void
*
)
rate
);
pthread_join
(
refillThread
,
NULL
);
nFleisch
=
n
;
}
count
++
;
usleep
(
time
);
nFleisch
--
;
}
printf
(
"fertig fleisch
\n
"
);
pthread_mutex_unlock
(
&
Fleisch
);
}
void
*
verkaufen
(
void
*
tid
)
{
while
(
nichtFertig
)
{
while
(
!
vectorCondition
[(
long
)
tid
])
{
int
max
=
3
;
int
num
;
for
(
int
c
=
0
;
c
<=
max
;
c
++
){
num
=
random
()
%
10
;
}
sumDoener
+=
num
;
getFleisch
(
num
,
t
);
getBrot
(
num
,
t
);
getSalat
(
num
,
t
);
getSauce
(
num
,
t
);
vectorCondition
[(
long
)
tid
]
=
0
;
// lock this thread again
printf
(
"Doener fertig verkaufer Thread No: %ld fuer kunde :%d , with time%ld
\n
"
,(
long
)
tid
,
vectorKundenBestellung
[(
long
)
tid
].
back
(),(
long
)
num
);
sem_post
(
&
listSem
[(
long
)
tid
]);
//go get ur bestellung mtf
}
}
pthread_exit
(
NULL
);
}
void
init_verkaufer
(
int
m
){
vectorKundenBestellung
.
resize
(
m
);
// save id der Kunden , vector«1» ist verkaufer 1, die neuste bestellung ist vector«1».back()
pthread_t
verkaufer_threads
[
m
];
int
status
;
long
i
;
listMutexVerkaufen
.
resize
(
m
);
listMutexMakeDoner
.
resize
(
m
);
for
(
i
=
0
;
i
<
m
;
i
++
)
{
listMutexVerkaufen
[
i
]
=
PTHREAD_MUTEX_INITIALIZER
;
listMutexMakeDoner
[
i
]
=
PTHREAD_MUTEX_INITIALIZER
;
vectorCondition
.
push_back
(
0
);
status
=
pthread_create
(
&
verkaufer_threads
[
i
],
NULL
,
verkaufen
,(
void
*
)
i
);
if
(
status
!=
0
)
{
printf
(
"error creating thread %ld
\n
"
,
i
);
exit
(
-
1
);
}
//if
}
// for
}
void
*
kunden
(
void
*
tid
)
{
sem_post
(
&
semaphoreKundenReihe
);
// do something
for
(
int
i
=
0
;
i
<
m
;
i
++
)
{
if
(
pthread_mutex_trylock
(
&
listMutexVerkaufen
[
i
])
==
0
){
// try to lock a verkaufer thread , if sucess, then lock it
printf
(
"kunden Thread No: %ld
\n
"
,(
long
)
tid
);
vectorKundenBestellung
[
i
].
push_back
((
long
)
tid
);
//long(tid) kunde come and orde at (i) verkaufer
vectorCondition
[
i
]
=
1
;
//to announce , that thread verkaufer (i) got a job
sem_wait
(
&
listSem
[
i
]);
// mwait verkaufer wake up
pthread_mutex_unlock
(
&
listMutexVerkaufen
[
i
]);
//unlock this thread
sem_post
(
&
semaphoreVerkaufer
);
// sem_post , ready for next kunden
break
;
}
}
pthread_exit
(
NULL
);
}
void
init_kunden
(
int
k
){
int
status
;
pthread_t
kunden_threads
[
k
];
auto
start
=
chrono
::
steady_clock
::
now
();
for
(
long
i
=
0
;
i
<
k
;
i
++
)
{
//listCondKunden.push_back(PTHREAD_COND_INITIALIZER);
sem_wait
(
&
semaphoreKundenReihe
);
// wait in reihe, darf nur maximal 1 person jede mal gehen, um condtion race zu vermeiden
sem_wait
(
&
semaphoreVerkaufer
);
// wait in reihe, darf 1 person gehen, wenn es einen freie verkaufer gibt
status
=
pthread_create
(
&
kunden_threads
[
i
],
NULL
,
kunden
,(
void
*
)
i
);
if
(
status
!=
0
)
{
printf
(
"error creating thread %ld
\n
"
,
i
);
exit
(
-
1
);
}
//if
}
for
(
int
i
=
0
;
i
<
k
;
i
++
)
{
if
(
i
==
k
-
1
){
pthread_join
(
kunden_threads
[
i
],
NULL
);
// wait all kunden finish
auto
end
=
chrono
::
steady_clock
::
now
();
auto
diff
=
end
-
start
;
auto
diff_sec
=
chrono
::
duration_cast
<
chrono
::
seconds
>
(
diff
);
std
::
cout
<<
diff_sec
.
count
()
<<
";"
<<
sumDoener
<<
std
::
endl
;
std
::
fstream
out
;
out
.
open
(
"time.txt"
,
std
::
ios
::
out
|
std
::
ios
::
app
);
out
<<
sumDoener
<<
";"
<<
diff_sec
.
count
()
<<
"
\n
"
;
out
.
close
();
nichtFertig
=
false
;
}
}
std
::
cout
<<
"ENDDDDDDDDD"
<<
std
::
endl
;
}
//imbiss <m> <n> <r> <k> <t>
// g++ 2.cpp -o 2 -pthread
int
main
(
int
argc
,
char
*
argv
[])
{
// k = 14;m=3;
// t = 50000;
// n = 5;
// r = 5;
m
=
atoi
(
argv
[
1
]);
n
=
atoi
(
argv
[
2
]);
r
=
atoi
(
argv
[
3
]);
k
=
atoi
(
argv
[
4
]);
t
=
atoi
(
argv
[
5
])
;
printf
(
"check %d
\n
"
,
m
);
nSauce
=
n
;
nBrot
=
n
;
nFleisch
=
n
;
nSalat
=
n
;
sem_init
(
&
sem0
,
0
,
0
);
sem_init
(
&
sem1
,
0
,
0
);
sem_init
(
&
sem2
,
0
,
0
);
sem_init
(
&
sem3
,
0
,
0
);
sem_init
(
&
sem4
,
0
,
0
);
listSem
.
push_back
(
sem0
);
listSem
.
push_back
(
sem1
);
listSem
.
push_back
(
sem2
);
listSem
.
push_back
(
sem3
);
listSem
.
push_back
(
sem4
);
init_verkaufer
(
m
);
sem_init
(
&
semaphoreVerkaufer
,
0
,
m
);
sem_init
(
&
semaphoreKundenReihe
,
0
,
1
);
init_kunden
(
k
);
return
0
;
}
//main
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment