From 39f6871fa59c134366b4292e450b4c5cf59bcd49 Mon Sep 17 00:00:00 2001 From: vq <1457480465@qq.com> Date: Wed, 13 Mar 2024 23:45:12 +0800 Subject: [PATCH] =?UTF-8?q?lab3=2005-=E5=A4=9A=E5=A4=84=E7=90=86=E5=99=A8?= =?UTF-8?q?=E7=BC=96=E7=A8=8B=E5=AE=9E=E9=AA=8C=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/c_cpp_properties.json | 20 +++++++++++ .vscode/extensions.json | 0 .vscode/settings.json | 7 ++-- 2024/lab3/hello.c | 19 ++++++++++ 2024/lab3/memory.c | 16 +++++++++ 2024/lab3/stack.c | 42 ++++++++++++++++++++++ 2024/lab3/thread.h | 68 +++++++++++++++++++++++++++++++++++ 7 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/extensions.json create mode 100644 2024/lab3/hello.c create mode 100644 2024/lab3/memory.c create mode 100644 2024/lab3/stack.c create mode 100644 2024/lab3/thread.h diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..de21154 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,20 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "compilerPath": "E:\\cpp\\mingw64\\bin\\gcc.exe", + "cStandard": "c17", + "cppStandard": "gnu++14", + "intelliSenseMode": "windows-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..e69de29 diff --git a/.vscode/settings.json b/.vscode/settings.json index d0f44eb..f7b636b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,9 @@ { "files.associations": { "dirent.h": "c", - "unordered_map": "cpp" - } + "unordered_map": "cpp", + "cstdio": "c", + "thread.h": "c" + }, + "C_Cpp.errorSquiggles": "disabled" } \ No newline at end of file diff --git a/2024/lab3/hello.c b/2024/lab3/hello.c new file mode 100644 index 0000000..844039c --- /dev/null +++ b/2024/lab3/hello.c @@ -0,0 +1,19 @@ +#include "thread.h" + +void T_a() { + while (1) { + printf("a"); + } +} + +void T_b() { + while (1) { + printf("b"); + } +} + +// pthead库不是标准linux库 -> 执行gcc thread.c -lpthread +int main() { + create(T_a); + create(T_b); +} \ No newline at end of file diff --git a/2024/lab3/memory.c b/2024/lab3/memory.c new file mode 100644 index 0000000..8f39dcc --- /dev/null +++ b/2024/lab3/memory.c @@ -0,0 +1,16 @@ +#include "thread.h" + + +// 多个线程之间是共享内存 +int n; + +void T_hello(int id) { + int i = n++; + printf("%d\n", i); +} + +int main() { + for (int i = 0; i < 10; i++) { + create(T_hello); + } +} \ No newline at end of file diff --git a/2024/lab3/stack.c b/2024/lab3/stack.c new file mode 100644 index 0000000..a1e36d1 --- /dev/null +++ b/2024/lab3/stack.c @@ -0,0 +1,42 @@ +#include "thread.h" + + +#define N 4 + +char * volatile low[N]; +char * volatile high[N]; + + +void update_range(int T, char *ptr) { + if (ptr < low[T]) { + low[T] = ptr; + } + if (ptr > high[T]) { + high[T] = ptr; + } +} + + +void probe(int T, int n) { + char scratch[64]; + update_range(T, scratch); + + printf("Stack(T%d) >= %ld KB\n", T, (high[T] - low[T]) / 1024); + + probe(T, n + 1); +} + +void T_probe(int T) { + T -= 1; + low[T] = (char *)-1; + high[T] = (char *)0; + probe(T, 0); +} + +int main() { + setbuf(stdout, NULL); + + for (int i = 0; i < N; i++) { + create(T_probe); + } +} \ No newline at end of file diff --git a/2024/lab3/thread.h b/2024/lab3/thread.h new file mode 100644 index 0000000..2c15ad1 --- /dev/null +++ b/2024/lab3/thread.h @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include + + +#define LENGTH(arr) (sizeof(arr) / sizeof(arr[0])) + +enum { + T_FREE = 0, // This slot is not used yet. + T_LIVE, // This thread is running. + T_DEAD, // This thread has terminated. +}; + +struct thread { + int id; // Thread number: 1, 2, ... + int status; // Thread status: FREE/LIVE/DEAD + pthread_t thread; // Thread struct + void (*entry)(int); // Entry point +}; + +static struct thread threads_[4096]; +static int n_ = 0; + +static inline +void *wrapper_(void *arg) { + struct thread *t = (struct thread *)arg; + t->entry(t->id); + return NULL; +} + +// Create a thread that calls function fn. +static inline +void create(void *fn) { + assert(n_ < LENGTH(threads_)); + + threads_[n_] = (struct thread) { + .id = n_ + 1, + .status = T_LIVE, + .entry = fn, + }; + pthread_create( + &(threads_[n_].thread), + NULL, + wrapper_, + &threads_[n_] + ); + n_++; +}; + +static inline +void join() { + for (int i = 0; i < LENGTH(threads_); i++) { + struct thread *t = &threads_[i]; + if (t->status == T_LIVE) { + pthread_join(t->thread, NULL); + t->status = T_DEAD; + } + } +} + +// Join all threads when main() returns; +__attribute__((destructor)) +static void cleanup() { + join(); +} \ No newline at end of file