Add initial lab 4
This commit is contained in:
parent
c6c7caeae7
commit
25ac7bc195
8
Lab4/.idea/.gitignore
vendored
Normal file
8
Lab4/.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
2
Lab4/.idea/Lab4.iml
Normal file
2
Lab4/.idea/Lab4.iml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
5
Lab4/.idea/codeStyles/codeStyleConfig.xml
Normal file
5
Lab4/.idea/codeStyles/codeStyleConfig.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||||
|
</state>
|
||||||
|
</component>
|
4
Lab4/.idea/misc.xml
Normal file
4
Lab4/.idea/misc.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
|
</project>
|
8
Lab4/.idea/modules.xml
Normal file
8
Lab4/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/Lab4.iml" filepath="$PROJECT_DIR$/.idea/Lab4.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
Lab4/.idea/vcs.xml
Normal file
6
Lab4/.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
Lab4/CMakeLists.txt
Normal file
6
Lab4/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
project(Lab4 C)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
|
add_executable(Lab4 Lab4.c)
|
100
Lab4/Lab4.c
Normal file
100
Lab4/Lab4.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Question 2: You see the number 1 most of the time. It is sometimes different because there are periods of time when the threads are reading/writing to the same place, but with the number of increments being 100, it is not likely that the threads will be reading/writing at the same time. In the CPU what happens is that a value is loaded into a register, while another thread completes a task, and then the value is written back to the memory. This leads to missing increments/decrements.
|
||||||
|
*
|
||||||
|
* Question 4: You see the number 1 often. Since the number of increments is 1000, the chance has increased for threads to be reading/writing at the same time. This leads to more missing increments/decrements.
|
||||||
|
*
|
||||||
|
* Question 6: You see the number 1 almost never. The number of loops at this point almost guarantees that the threads will be reading/writing at the same time, and the counter missing increments/decrements.
|
||||||
|
*
|
||||||
|
* Question 8: The number 1 is the only thing displayed. This is because the mutex lock ensures that the threads will not be reading/writing at the same time, and the counter will not miss increments/decrements. When another thread tried to lock the mutex, it waits for it to first become unlocked, ensuring proper thread synchronization.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include<pthread.h>
|
||||||
|
#include<stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
#define RANDOM_WITHIN_RANGE(a, b, seed) (rand_r(&seed)%b+a)
|
||||||
|
|
||||||
|
int gv = 1;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
sem_t sem;
|
||||||
|
|
||||||
|
#define loop 10000
|
||||||
|
|
||||||
|
void *inc() {
|
||||||
|
for (int i = 0; i < loop; i++) {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
gv++;
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *dec() {
|
||||||
|
for (int i = 0; i < loop; i++) {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
gv--;
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *minus() {
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
printf("-");
|
||||||
|
sem_wait(&sem);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *plus(void *argg) {
|
||||||
|
unsigned int seed = *((unsigned int *) argg);
|
||||||
|
int interval = RANDOM_WITHIN_RANGE(100000, 500000, seed);
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
printf("+");
|
||||||
|
//usleep(interval);
|
||||||
|
sem_post(&sem);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// Init Mutex
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
// Create thread pool and run threads
|
||||||
|
pthread_t thread[2];
|
||||||
|
pthread_create(&thread[i], NULL, &inc, NULL);
|
||||||
|
pthread_create(&thread[i + 1], NULL, &dec, NULL);
|
||||||
|
// Wait for threads to finish
|
||||||
|
pthread_join(thread[i], NULL);
|
||||||
|
pthread_join(thread[i + 1], NULL);
|
||||||
|
// Destroy Mutex
|
||||||
|
pthread_mutex_destroy(&mutex);
|
||||||
|
// Print final value
|
||||||
|
printf("%d\n", gv);
|
||||||
|
|
||||||
|
// Init Semaphore
|
||||||
|
sem_init(&sem, 0, 0);
|
||||||
|
for (i = 0; i < 1; i++) {
|
||||||
|
unsigned int *t = (unsigned int *) malloc(sizeof(unsigned int));
|
||||||
|
*t = rand();
|
||||||
|
|
||||||
|
pthread_create(&(thread[i]), NULL, &plus, (void *) t);
|
||||||
|
pthread_create(&(thread[i + 1]), NULL, &minus, NULL);
|
||||||
|
|
||||||
|
pthread_join(thread[i], NULL);
|
||||||
|
pthread_join(thread[i + 1], NULL);
|
||||||
|
}
|
||||||
|
sem_destroy(&sem);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//TODO: Delete this comment
|
||||||
|
//Semaphore doesn't work because it increments the semaphore all at once before the other thread even gets the chance to print
|
||||||
|
//Just as an example to fix it you would need two semaphores so you can signal back and forth between the two threads
|
BIN
Lab4/documentation/Lab4.pdf
Normal file
BIN
Lab4/documentation/Lab4.pdf
Normal file
Binary file not shown.
8
Lab4/run.sh
Normal file
8
Lab4/run.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
output=$(./build/Lab4)
|
||||||
|
if [ "$output" != "1" ]; then
|
||||||
|
echo "$output"
|
||||||
|
fi
|
||||||
|
done
|
Loading…
Reference in New Issue
Block a user