From f8ae30583d3d70c6b81b20c5904ea63625219b21 Mon Sep 17 00:00:00 2001 From: ChoChoX Date: Thu, 14 May 2026 09:27:48 +0800 Subject: [PATCH] test --- .vscode/tasks.json | 28 +++ exp1/.vscode/launch.json | 7 + exp1/.vscode/tasks.json | 28 +++ exp1/badcount | Bin 0 -> 18648 bytes exp1/badcount.c | 62 ++++++ exp1/task61 | Bin 0 -> 19112 bytes exp1/task61.c | 53 ++++++ .../2024414290124-吕锦中-lab6.tar.gz | Bin 0 -> 4943 bytes 吕锦中202441429012406/badcount.c | 34 ++++ 吕锦中202441429012406/matmult.c | 145 ++++++++++++++ 吕锦中202441429012406/psum64.c | 66 +++++++ 吕锦中202441429012406/task61.c | 58 ++++++ 吕锦中202441429012406/task62.c | 44 +++++ 吕锦中202441429012406/task63.c | 176 +++++++++++++++++ 吕锦中202441429012406/task64.c | 70 +++++++ 吕锦中202441429012406/task66.c | 59 ++++++ 吕锦中202441429012406/task67.c | 177 ++++++++++++++++++ 17 files changed, 1007 insertions(+) create mode 100644 .vscode/tasks.json create mode 100644 exp1/.vscode/launch.json create mode 100644 exp1/.vscode/tasks.json create mode 100755 exp1/badcount create mode 100644 exp1/badcount.c create mode 100755 exp1/task61 create mode 100644 exp1/task61.c create mode 100644 吕锦中202441429012406/2024414290124-吕锦中-lab6.tar.gz create mode 100644 吕锦中202441429012406/badcount.c create mode 100644 吕锦中202441429012406/matmult.c create mode 100644 吕锦中202441429012406/psum64.c create mode 100644 吕锦中202441429012406/task61.c create mode 100644 吕锦中202441429012406/task62.c create mode 100644 吕锦中202441429012406/task63.c create mode 100644 吕锦中202441429012406/task64.c create mode 100644 吕锦中202441429012406/task66.c create mode 100644 吕锦中202441429012406/task67.c diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..5d4653d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc 生成活动文件", + "command": "/usr/bin/gcc", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "调试器生成的任务。" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/exp1/.vscode/launch.json b/exp1/.vscode/launch.json new file mode 100644 index 0000000..f980ab9 --- /dev/null +++ b/exp1/.vscode/launch.json @@ -0,0 +1,7 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [] +} \ No newline at end of file diff --git a/exp1/.vscode/tasks.json b/exp1/.vscode/tasks.json new file mode 100644 index 0000000..5d4653d --- /dev/null +++ b/exp1/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc 生成活动文件", + "command": "/usr/bin/gcc", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "调试器生成的任务。" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/exp1/badcount b/exp1/badcount new file mode 100755 index 0000000000000000000000000000000000000000..01e78928a7326ede5b6eec039b8b3843adc93b90 GIT binary patch literal 18648 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

>&!(f zT(V(EC`XaXCrepY=ZXa=Qlqu}8Ph6;a|lRyJef}C3YqXo&Mplmv8y9#Wm0G>_IqTo zKg8MZAvcadamtO9+Awko!f{uav~A0=OmRaOVb{bn& zoJ_6=`aTKQ1J;(`u6WI8yrf~&#rwEI$^e)7lJ<1-_F)%br@CJ%a}iSVm`8rMlJj_$ z?T3-k#2V2Vb0kzhO0?pwiC)3uQz^vZG5n}p9v`#(cahOB%H;hpEdLTROSN~oc70v? z=@#kr>|v2E^5RerqwPb_0kkLpkrp0ksXclr7Rk1tvN z6v=6qlLGM#`i~&*M1NQvV@rq9=%pLy{hAuz%6CFgeO}pn+xutA-aCHzij>#-Choh- z$o~#px4WlKE9=jX6CRB;OZn}9^^kwycComh?D0UL&{e0s z(oef+QYVxBi-%K|JrF6<-ESmk*vX85pk$XvM{yfk+{b3vV@8U0vXx+&E*hD9aU_{H z(zq3ujAVI2q>5wXdDAx2kLKAmX%isg0==`l&v`t0)U})cjC84JWRrz7 zZ44Yf0vw)6M!96B1>%E)F;XfiZ}KtA4{YZ#m%iwFi0 zrZq04G>eC~h@>YA@ZeC}ax|y#x*3nq8peRmGV@6SsN8toCXc921ldTYs4^upB_g&t z0hYQStc&s_M$D}0aM?7xF()E!MKRJCH!XWoiT3Or##kid6ykJE$0g@cm*iLur8)j_ z?nDIF#2C6dWadaY1IuI~g9}Kpxx#3X^U0AB%RI##w*8u%M+7-bVsr?r`nvvQ^R(VW zYb3ZW$h6#kaHYmGvNlD);#TJ3m)oDuD6*|i+rj)4Yb0DguOl(tpp3a(OiOA~3>+pP zZuz{<#5AA^q?tEm8BcQzN(uaEZHCLAQw1@7j*P03xBf?=qctGL^STeyUWMiQvmH~K z8q=B*^XKFe0oKzL-K_B5`YW->BSXF!&+A++Rfb%?xBaISey_6Qbu*?DRd|Y-7e56V z#e~=S+~t|O*OY?kX+AL?JiGl951z+eOnJSQ?Y;5)Q-ybn2`NiOcPN&L7ym32 zRDZ_vIF#u=1}f^sf5U^H3OR;M=M|0#_aElJgG}}P$NT>!HnX9kUi_;bJkLv*hCFz0 z{jWn$i$J_S%ku*Me-7UAm}mMnupL!+o`+n-CJ{<(=WvTW%YOj{T{~Pp&ky+jdfcRw zgQRW;u0QU7zXu(eFrMcN7ovp1_fHOSk6bR(Mu4mFBBo4L;JF-jz&Pex0VWxj&*R@t zh4{DY9vl!N;NJxeIjdII+yDNu)NJDto&J +#include +#include +#include +#include + +int cnt = 0; +sem_t mutex; + +void *increase(void *vargp) +{ + unsigned int niters = (unsigned int)vargp; + for (unsigned int i = 0; i < niters; i++) + { + sem_wait(&mutex); + cnt++; + sem_post(&mutex); + } + return NULL; +} + +void *decrease(void *vargp) +{ + unsigned int niters = (unsigned int)vargp; + for (unsigned int i = 0; i < niters; i++) + { + sem_wait(&mutex); + cnt--; + sem_post(&mutex); + } + return NULL; +} + +int main(int argc, char **argv) +{ + unsigned int niters; + pthread_t t1,t2; + + if (argc != 2) + { + printf("Usage: %s \n", argv[0]); + exit(2); + } + niters = atoll(argv[1]); + + sem_init(&mutex, 0, 1); + pthread_create(&t1,NULL,increase,(void*)niters); + pthread_create(&t2,NULL,decrease,(void*)niters); + pthread_join(t1,NULL); + pthread_join(t2,NULL); + + if (cnt != 0) + { + printf("Error! cnt=%d\n", cnt); + } + else + { + printf("Correct! cnt=%d\n", cnt); + } + sem_destroy(&mutex); + exit(0); +} \ No newline at end of file diff --git a/exp1/task61 b/exp1/task61 new file mode 100755 index 0000000000000000000000000000000000000000..1b8468a66e3ee244cda18fffdf2470ef0938bcd9 GIT binary patch literal 19112 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 literal 0 HcmV?d00001 diff --git a/exp1/task61.c b/exp1/task61.c new file mode 100644 index 0000000..67dee6d --- /dev/null +++ b/exp1/task61.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include + +void *wokerT1(void *vargp) +{ + for(int i=0; i<5; i++) + { + printf("My name is Lvjinzhong\n"); + int sleep_time = rand() % 5 + 1; + sleep(sleep_time); + } + return NULL; +} + +void *wokerT2(void *vargp) +{ + for(int i=0; i<5; i++) + { + printf("My student number is 2024414290124\n"); + int sleep_time = rand() % 5 + 1; + sleep(sleep_time); + } + return NULL; +} + +void *wokerT3(void *vargp) +{ + for(int i=0; i<5; i++) + { + time_t t = time(NULL); + printf("Current time %s\n",ctime(&t)); + int sleep_time = rand() % 5 + 1; + sleep(sleep_time); + } + return NULL; +} + +int main() +{ + pthread_t t1,t2,t3; + pthread_create(&t1, NULL, wokerT1, NULL); + pthread_create(&t2, NULL, wokerT2, NULL); + pthread_create(&t3, NULL, wokerT3, NULL); + + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + pthread_join(t3, NULL); + return 0; +} \ No newline at end of file diff --git a/吕锦中202441429012406/2024414290124-吕锦中-lab6.tar.gz b/吕锦中202441429012406/2024414290124-吕锦中-lab6.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..81e1f2f72e726d694a19983ea5b93ffd2943d502 GIT binary patch literal 4943 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 N{|EGHRGk2L006dlpJV_4 literal 0 HcmV?d00001 diff --git a/吕锦中202441429012406/badcount.c b/吕锦中202441429012406/badcount.c new file mode 100644 index 0000000..5a10fe9 --- /dev/null +++ b/吕锦中202441429012406/badcount.c @@ -0,0 +1,34 @@ +#include +#include +#include + +volatile long long counter = 0; +long long niters; + +void *thread_func(void *arg) { + for (long long i = 0; i < niters; i++) { + counter++; + } + return NULL; +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + niters = atoll(argv[1]); + + pthread_t t1, t2; + pthread_create(&t1, NULL, thread_func, NULL); + pthread_create(&t2, NULL, thread_func, NULL); + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + + printf("Expected: %lld, Got: %lld\n", 2 * niters, counter); + if (counter != 2 * niters) { + printf("ERROR: Race condition detected!\n"); + } + return 0; +} diff --git a/吕锦中202441429012406/matmult.c b/吕锦中202441429012406/matmult.c new file mode 100644 index 0000000..fff4cb7 --- /dev/null +++ b/吕锦中202441429012406/matmult.c @@ -0,0 +1,145 @@ +#include +#include +#include +#include +#include + +#define MAX_THREADS 64 + +int N; +double **A, **B, **C_parallel, **C_serial; +int nthreads; +int rows_per_thread; + +void **allocate_matrix(int n) { + double **mat = (double **)malloc(n * sizeof(double *)); + for (int i = 0; i < n; i++) { + mat[i] = (double *)malloc(n * sizeof(double)); + } + return (void **)mat; +} + +void free_matrix(double **mat, int n) { + for (int i = 0; i < n; i++) free(mat[i]); + free(mat); +} + +void init_matrix(double **mat, int n) { + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + mat[i][j] = (double)(rand() % 100) / 10.0; +} + +void *multiply_thread(void *arg) { + int start_row = *(int *)arg; + int end_row = start_row + rows_per_thread; + if (end_row > N) end_row = N; + + for (int i = start_row; i < end_row; i++) { + for (int j = 0; j < N; j++) { + double sum = 0.0; + for (int k = 0; k < N; k++) { + sum += A[i][k] * B[k][j]; + } + C_parallel[i][j] = sum; + } + } + return NULL; +} + +void serial_multiply() { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + double sum = 0.0; + for (int k = 0; k < N; k++) { + sum += A[i][k] * B[k][j]; + } + C_serial[i][j] = sum; + } + } +} + +double get_time() { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; +} + +int verify() { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if (C_parallel[i][j] - C_serial[i][j] > 0.001 || + C_serial[i][j] - C_parallel[i][j] > 0.001) { + printf("Mismatch at [%d][%d]: parallel=%.6f, serial=%.6f\n", + i, j, C_parallel[i][j], C_serial[i][j]); + return 0; + } + } + } + return 1; +} + +int main(int argc, char *argv[]) { + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + N = atoi(argv[1]); + nthreads = atoi(argv[2]); + if (nthreads > MAX_THREADS) nthreads = MAX_THREADS; + if (nthreads > N) nthreads = N; + + rows_per_thread = N / nthreads; + + srand(42); + + A = (double **)allocate_matrix(N); + B = (double **)allocate_matrix(N); + C_parallel = (double **)allocate_matrix(N); + C_serial = (double **)allocate_matrix(N); + + init_matrix(A, N); + init_matrix(B, N); + + pthread_t threads[MAX_THREADS]; + int starts[MAX_THREADS]; + + double t_start = get_time(); + + for (int i = 0; i < nthreads; i++) { + starts[i] = i * rows_per_thread; + pthread_create(&threads[i], NULL, multiply_thread, &starts[i]); + } + for (int i = 0; i < nthreads; i++) { + pthread_join(threads[i], NULL); + } + + double t_end = get_time(); + double t_parallel = t_end - t_start; + + /* Serial version for verification */ + t_start = get_time(); + serial_multiply(); + t_end = get_time(); + double t_serial = t_end - t_start; + + printf("Matrix size: %d x %d, Threads: %d\n", N, N, nthreads); + printf("Parallel time: %.6f s\n", t_parallel); + printf("Serial time: %.6f s\n", t_serial); + printf("Speedup: %.4f\n", t_serial / t_parallel); + printf("Efficiency: %.4f\n", t_serial / t_parallel / nthreads); + + if (verify()) { + printf("Verification: SUCCESS\n"); + } else { + printf("Verification: FAILED\n"); + } + + free_matrix(A, N); + free_matrix(B, N); + free_matrix(C_parallel, N); + free_matrix(C_serial, N); + + return 0; +} diff --git a/吕锦中202441429012406/psum64.c b/吕锦中202441429012406/psum64.c new file mode 100644 index 0000000..afcf8fe --- /dev/null +++ b/吕锦中202441429012406/psum64.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +#define MAX_THREADS 64 +#define N 1000000000LL + +long long global_sum = 0; +long long nelems_per_thread; +pthread_mutex_t mutex; + +void *sum_thread(void *arg) { + long long start = *(long long *)arg; + long long local_sum = 0; + long long end = start + nelems_per_thread; + if (end > N) end = N; + for (long long i = start; i < end; i++) { + local_sum += i; + } + pthread_mutex_lock(&mutex); + global_sum += local_sum; + pthread_mutex_unlock(&mutex); + return NULL; +} + +double get_time() { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + int nthreads = atoi(argv[1]); + if (nthreads > MAX_THREADS) nthreads = MAX_THREADS; + + nelems_per_thread = N / nthreads; + pthread_mutex_init(&mutex, NULL); + + pthread_t threads[MAX_THREADS]; + long long starts[MAX_THREADS]; + + double t_start = get_time(); + + for (int i = 0; i < nthreads; i++) { + starts[i] = i * nelems_per_thread; + pthread_create(&threads[i], NULL, sum_thread, &starts[i]); + } + + for (int i = 0; i < nthreads; i++) { + pthread_join(threads[i], NULL); + } + + double t_end = get_time(); + double elapsed = t_end - t_start; + + printf("Threads: %d, Sum: %lld, Time: %.6f s\n", nthreads, global_sum, elapsed); + + pthread_mutex_destroy(&mutex); + return 0; +} diff --git a/吕锦中202441429012406/task61.c b/吕锦中202441429012406/task61.c new file mode 100644 index 0000000..93b86d7 --- /dev/null +++ b/吕锦中202441429012406/task61.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include + +void *thread_T1(void *arg) { + for (int i = 1; i <= 5; i++) { + printf("My name is 吕锦中\n"); + if (i < 5) { + int sleep_time = rand() % 5 + 1; + sleep(sleep_time); + } + } + return NULL; +} + +void *thread_T2(void *arg) { + for (int i = 1; i <= 5; i++) { + printf("My student number is 2024414290124\n"); + if (i < 5) { + int sleep_time = rand() % 5 + 1; + sleep(sleep_time); + } + } + return NULL; +} + +void *thread_T3(void *arg) { + for (int i = 1; i <= 5; i++) { + time_t now = time(NULL); + struct tm *tm_info = localtime(&now); + char time_str[64]; + strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info); + printf("Current time %s\n", time_str); + if (i < 5) { + int sleep_time = rand() % 5 + 1; + sleep(sleep_time); + } + } + return NULL; +} + +int main() { + srand(time(NULL)); + pthread_t t1, t2, t3; + + pthread_create(&t1, NULL, thread_T1, NULL); + pthread_create(&t2, NULL, thread_T2, NULL); + pthread_create(&t3, NULL, thread_T3, NULL); + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + pthread_join(t3, NULL); + + printf("All threads finished.\n"); + return 0; +} diff --git a/吕锦中202441429012406/task62.c b/吕锦中202441429012406/task62.c new file mode 100644 index 0000000..be4caa5 --- /dev/null +++ b/吕锦中202441429012406/task62.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +long long counter = 0; +long long niters; +sem_t mutex; + +void *thread_func(void *arg) { + for (long long i = 0; i < niters; i++) { + sem_wait(&mutex); + counter++; + sem_post(&mutex); + } + return NULL; +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + niters = atoll(argv[1]); + + sem_init(&mutex, 0, 1); + + pthread_t t1, t2; + pthread_create(&t1, NULL, thread_func, NULL); + pthread_create(&t2, NULL, thread_func, NULL); + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + + sem_destroy(&mutex); + + printf("Expected: %lld, Got: %lld\n", 2 * niters, counter); + if (counter == 2 * niters) { + printf("SUCCESS: No race condition.\n"); + } else { + printf("ERROR: Race condition detected!\n"); + } + return 0; +} diff --git a/吕锦中202441429012406/task63.c b/吕锦中202441429012406/task63.c new file mode 100644 index 0000000..9f1ad48 --- /dev/null +++ b/吕锦中202441429012406/task63.c @@ -0,0 +1,176 @@ +#include +#include +#include +#include +#include +#include + +#define POISON -1 + +typedef struct { + int *buf; + int n; + int outpos; + int inpos; + sem_t mutex; + sem_t slots; + sem_t items; +} sbuf_t; + +long long produced_sum = 0; +long long consumed_sum = 0; +sem_t sum_mutex; +int consumed_count = 0; +int total_items; +sem_t count_mutex; + +void sbuf_init(sbuf_t *sp, int n) { + sp->buf = (int *)malloc(n * sizeof(int)); + sp->n = n; + sp->outpos = 0; + sp->inpos = 0; + sem_init(&sp->mutex, 0, 1); + sem_init(&sp->slots, 0, n); + sem_init(&sp->items, 0, 0); +} + +void sbuf_deinit(sbuf_t *sp) { + free(sp->buf); + sem_destroy(&sp->mutex); + sem_destroy(&sp->slots); + sem_destroy(&sp->items); +} + +void sbuf_insert(sbuf_t *sp, int item) { + sem_wait(&sp->slots); + sem_wait(&sp->mutex); + sp->buf[sp->inpos] = item; + sp->inpos = (sp->inpos + 1) % sp->n; + sem_post(&sp->mutex); + sem_post(&sp->items); +} + +int sbuf_remove(sbuf_t *sp) { + sem_wait(&sp->items); + sem_wait(&sp->mutex); + int item = sp->buf[sp->outpos]; + sp->outpos = (sp->outpos + 1) % sp->n; + sem_post(&sp->mutex); + sem_post(&sp->slots); + return item; +} + +typedef struct { + sbuf_t *sp; + int num_items; + int id; +} producer_arg_t; + +typedef struct { + sbuf_t *sp; + int id; +} consumer_arg_t; + +void *producer(void *arg) { + producer_arg_t *pa = (producer_arg_t *)arg; + for (int i = 0; i < pa->num_items; i++) { + int val = rand() % 1000; + sbuf_insert(pa->sp, val); + sem_wait(&sum_mutex); + produced_sum += val; + sem_post(&sum_mutex); + printf("[Producer %d] produced %d\n", pa->id, val); + } + return NULL; +} + +void *consumer(void *arg) { + consumer_arg_t *ca = (consumer_arg_t *)arg; + while (1) { + int item = sbuf_remove(ca->sp); + if (item == POISON) { + /* Put poison back for other consumers, then exit */ + sbuf_insert(ca->sp, POISON); + break; + } + sem_wait(&sum_mutex); + consumed_sum += item; + sem_post(&sum_mutex); + sem_wait(&count_mutex); + consumed_count++; + sem_post(&count_mutex); + printf("[Consumer %d] consumed %d\n", ca->id, item); + } + return NULL; +} + +int main(int argc, char *argv[]) { + if (argc != 5) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + int k = atoi(argv[1]); + int items_per_producer = atoi(argv[2]); + int m = atoi(argv[3]); + int N = atoi(argv[4]); + total_items = k * items_per_producer; + + srand(time(NULL)); + sem_init(&sum_mutex, 0, 1); + sem_init(&count_mutex, 0, 1); + + sbuf_t buf; + sbuf_init(&buf, N); + + pthread_t *producers = malloc(k * sizeof(pthread_t)); + pthread_t *consumers = malloc(m * sizeof(pthread_t)); + producer_arg_t *pargs = malloc(k * sizeof(producer_arg_t)); + consumer_arg_t *cargs = malloc(m * sizeof(consumer_arg_t)); + + for (int i = 0; i < k; i++) { + pargs[i].sp = &buf; + pargs[i].num_items = items_per_producer; + pargs[i].id = i + 1; + pthread_create(&producers[i], NULL, producer, &pargs[i]); + } + + for (int i = 0; i < m; i++) { + cargs[i].sp = &buf; + cargs[i].id = i + 1; + pthread_create(&consumers[i], NULL, consumer, &cargs[i]); + } + + /* Wait for all producers to finish */ + for (int i = 0; i < k; i++) { + pthread_join(producers[i], NULL); + } + + /* Insert one poison pill to start the termination chain */ + sbuf_insert(&buf, POISON); + + /* Wait for all consumers to finish */ + for (int i = 0; i < m; i++) { + pthread_join(consumers[i], NULL); + } + + printf("\n=== Verification ===\n"); + printf("Produced sum : %lld\n", produced_sum); + printf("Consumed sum : %lld\n", consumed_sum); + if (produced_sum == consumed_sum) { + printf("SUCCESS: Sums match! Program is correct.\n"); + } else { + printf("ERROR: Sum mismatch! Difference = %lld\n", + produced_sum - consumed_sum); + } + + free(producers); + free(consumers); + free(pargs); + free(cargs); + sbuf_deinit(&buf); + sem_destroy(&sum_mutex); + sem_destroy(&count_mutex); + + return 0; +} diff --git a/吕锦中202441429012406/task64.c b/吕锦中202441429012406/task64.c new file mode 100644 index 0000000..4d1978d --- /dev/null +++ b/吕锦中202441429012406/task64.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include + +#define MAX_THREADS 64 +#define N 1000000000LL + +long long global_sum = 0; +long long nelems_per_thread; +pthread_mutex_t mutex; + +void *sum_squares_thread(void *arg) { + long long start = *(long long *)arg; + long long end = start + nelems_per_thread; + if (end > N) end = N; + long long local_sum = 0; + for (long long i = start; i < end; i++) { + local_sum += i * i; + } + pthread_mutex_lock(&mutex); + global_sum += local_sum; + pthread_mutex_unlock(&mutex); + return NULL; +} + +double get_time() { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + int nthreads = atoi(argv[1]); + if (nthreads > MAX_THREADS) nthreads = MAX_THREADS; + + nelems_per_thread = N / nthreads; + pthread_mutex_init(&mutex, NULL); + + pthread_t threads[MAX_THREADS]; + long long starts[MAX_THREADS]; + + double t_start = get_time(); + + for (int i = 0; i < nthreads; i++) { + starts[i] = i * nelems_per_thread; + pthread_create(&threads[i], NULL, sum_squares_thread, &starts[i]); + } + + for (int i = 0; i < nthreads; i++) { + pthread_join(threads[i], NULL); + } + + double t_end = get_time(); + double elapsed = t_end - t_start; + + /* Expected sum of squares: (n-1)*n*(2n-1)/6 */ + long long expected = (N - 1) * N * (2 * N - 1) / 6; + printf("Threads: %d, Sum of squares: %lld, Expected: %lld, Time: %.6f s\n", + nthreads, global_sum, expected, elapsed); + + pthread_mutex_destroy(&mutex); + return 0; +} diff --git a/吕锦中202441429012406/task66.c b/吕锦中202441429012406/task66.c new file mode 100644 index 0000000..79a8bdf --- /dev/null +++ b/吕锦中202441429012406/task66.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include + +#define ITERATIONS 10000 + +double get_time() { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; +} + +void *dummy_thread(void *arg) { + return NULL; +} + +int main() { + double t_start, t_end; + double fork_total = 0, pthread_total = 0; + + /* Measure fork() */ + t_start = get_time(); + for (int i = 0; i < ITERATIONS; i++) { + pid_t pid = fork(); + if (pid == 0) { + _exit(0); + } else if (pid > 0) { + waitpid(pid, NULL, 0); + } + } + t_end = get_time(); + fork_total = t_end - t_start; + + /* Measure pthread_create() */ + t_start = get_time(); + for (int i = 0; i < ITERATIONS; i++) { + pthread_t tid; + pthread_create(&tid, NULL, dummy_thread, NULL); + pthread_join(tid, NULL); + } + t_end = get_time(); + pthread_total = t_end - t_start; + + printf("=== Performance Comparison ===\n"); + printf("Iterations: %d\n", ITERATIONS); + printf("fork() total time: %.6f s (avg: %.3f us)\n", + fork_total, fork_total / ITERATIONS * 1000000); + printf("pthread_create() total time: %.6f s (avg: %.3f us)\n", + pthread_total, pthread_total / ITERATIONS * 1000000); + printf("Ratio (fork/pthread): %.2fx\n", fork_total / pthread_total); + printf("\nExplanation: fork() creates a new process with a copy of the\n"); + printf("entire address space, which is much heavier than pthread_create()\n"); + printf("which only creates a new thread sharing the same address space.\n"); + + return 0; +} diff --git a/吕锦中202441429012406/task67.c b/吕锦中202441429012406/task67.c new file mode 100644 index 0000000..6264274 --- /dev/null +++ b/吕锦中202441429012406/task67.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include + +typedef struct { + int *buf; + int n; + int outpos; + int inpos; + sem_t mutex; + sem_t slots; + sem_t items; +} sbuf_t; + +int num_workers = 5; +int target_workers = 5; +pthread_mutex_t worker_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_t *workers = NULL; +sbuf_t *sbuf_ptr = NULL; +volatile int running = 1; + +void sbuf_init(sbuf_t *sp, int n) { + sp->buf = (int *)malloc(n * sizeof(int)); + sp->n = n; + sp->outpos = 0; + sp->inpos = 0; + sem_init(&sp->mutex, 0, 1); + sem_init(&sp->slots, 0, n); + sem_init(&sp->items, 0, 0); +} + +void sbuf_deinit(sbuf_t *sp) { + free(sp->buf); + sem_destroy(&sp->mutex); + sem_destroy(&sp->slots); + sem_destroy(&sp->items); +} + +void sbuf_insert(sbuf_t *sp, int item) { + sem_wait(&sp->slots); + sem_wait(&sp->mutex); + sp->buf[sp->inpos] = item; + sp->inpos = (sp->inpos + 1) % sp->n; + sem_post(&sp->mutex); + sem_post(&sp->items); +} + +int sbuf_remove(sbuf_t *sp) { + sem_wait(&sp->items); + sem_wait(&sp->mutex); + int item = sp->buf[sp->outpos]; + sp->outpos = (sp->outpos + 1) % sp->n; + sem_post(&sp->mutex); + sem_post(&sp->slots); + return item; +} + +void *worker_thread(void *arg) { + int id = *(int *)arg; + free(arg); + sbuf_t *sp = sbuf_ptr; + + while (running) { + int seconds = sbuf_remove(sp); + if (seconds == -1) break; + printf("[Worker %d] executing task: sleep %d seconds\n", id, seconds); + sleep(seconds); + printf("[Worker %d] task completed\n", id); + } + return NULL; +} + +void adjust_workers() { + pthread_mutex_lock(&worker_mutex); + int current = num_workers; + int target = target_workers; + + if (target > current) { + /* Increase workers */ + workers = realloc(workers, target * sizeof(pthread_t)); + for (int i = current; i < target; i++) { + int *id = malloc(sizeof(int)); + *id = i + 1; + pthread_create(&workers[i], NULL, worker_thread, id); + } + num_workers = target; + } else if (target < current) { + /* Decrease workers - insert poison pills */ + int to_remove = current - target; + for (int i = 0; i < to_remove; i++) { + sbuf_insert(sbuf_ptr, -1); + } + for (int i = target; i < current; i++) { + pthread_join(workers[i], NULL); + } + num_workers = target; + } + pthread_mutex_unlock(&worker_mutex); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + int buf_size = atoi(argv[1]); + sbuf_t buf; + sbuf_ptr = &buf; + sbuf_init(&buf, buf_size); + + /* Create initial 5 workers */ + workers = malloc(5 * sizeof(pthread_t)); + for (int i = 0; i < 5; i++) { + int *id = malloc(sizeof(int)); + *id = i + 1; + pthread_create(&workers[i], NULL, worker_thread, id); + } + + printf("=== Dynamic Thread Pool ===\n"); + printf("Commands:\n"); + printf(" - Add tasks\n"); + printf(" quit - Exit\n"); + printf("Initial workers: %d, Buffer size: %d\n\n", num_workers, buf_size); + + char line[256]; + while (1) { + printf("> "); + fflush(stdout); + if (!fgets(line, sizeof(line), stdin)) break; + + if (strncmp(line, "quit", 4) == 0) break; + + int task_count, seconds; + if (sscanf(line, "%d %d", &task_count, &seconds) == 2) { + printf("Adding %d tasks, each %d seconds...\n", task_count, seconds); + + for (int i = 0; i < task_count; i++) { + /* Check if buffer is full - double workers */ + int slots_avail; + sem_getvalue(&buf.slots, &slots_avail); + if (slots_avail == 0) { + target_workers = num_workers * 2; + printf("Buffer full, doubling workers to %d\n", target_workers); + adjust_workers(); + } + + sbuf_insert(&buf, seconds); + + /* Check if buffer is empty - halve workers */ + int items_avail; + sem_getvalue(&buf.items, &items_avail); + if (items_avail == 0 && num_workers > 2) { + target_workers = num_workers / 2; + if (target_workers < 2) target_workers = 2; + printf("Buffer empty, halving workers to %d\n", target_workers); + adjust_workers(); + } + } + } else { + printf("Invalid command. Usage: \n"); + } + } + + /* Shutdown */ + running = 0; + target_workers = 0; + adjust_workers(); + + sbuf_deinit(&buf); + free(workers); + printf("Done.\n"); + return 0; +}