From 8df60e2dc65ee60e74f939b5ab6e529e9af9ef7b Mon Sep 17 00:00:00 2001 From: flykhan Date: Mon, 21 Aug 2023 19:45:29 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BA=BF=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- day6/thread1.c | 10 +++++++ day6/thread10.c | 38 ++++++++++++++++++++++++++ day6/thread11.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ day6/thread12.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ day6/thread2.c | 21 ++++++++++++++ day6/thread3.c | 37 +++++++++++++++++++++++++ day6/thread4.c | 40 +++++++++++++++++++++++++++ day6/thread6.c | 37 +++++++++++++++++++++++++ day6/thread7.c | 46 +++++++++++++++++++++++++++++++ day6/thread7_2.c | 35 ++++++++++++++++++++++++ day6/thread8.c | 50 ++++++++++++++++++++++++++++++++++ day6/thread8_2.c | 44 ++++++++++++++++++++++++++++++ day6/thread9.c | 49 +++++++++++++++++++++++++++++++++ 13 files changed, 546 insertions(+) create mode 100644 day6/thread1.c create mode 100644 day6/thread10.c create mode 100644 day6/thread11.c create mode 100644 day6/thread12.c create mode 100644 day6/thread2.c create mode 100644 day6/thread3.c create mode 100644 day6/thread4.c create mode 100644 day6/thread6.c create mode 100644 day6/thread7.c create mode 100644 day6/thread7_2.c create mode 100644 day6/thread8.c create mode 100644 day6/thread8_2.c create mode 100644 day6/thread9.c diff --git a/day6/thread1.c b/day6/thread1.c new file mode 100644 index 0000000..57887d2 --- /dev/null +++ b/day6/thread1.c @@ -0,0 +1,10 @@ +#include +#include + +int main() +{ + printf("当前线程号: %ld", pthread_self()); // 获取当前线程号 + char test_char = getchar(); //阻塞程序的执行,等待用户输入一个字符后才会继续执行后面的代码 + printf("获取到 %c\n", test_char); + return 0; +} \ No newline at end of file diff --git a/day6/thread10.c b/day6/thread10.c new file mode 100644 index 0000000..6015116 --- /dev/null +++ b/day6/thread10.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include + +// pthread_cleanup_push() 和 pthread_cleanup_pop() +// 线程清退示例 +void *clear_task(void *args); +void *task1(void *data) +{ + char *p = malloc(32); + pthread_cleanup_push(clear_task, (void *)p); + strcpy(p, "hello, disen!"); + + printf("%ld 线程在堆中分配的空间,内容为 %s\n", pthread_self(), p); + pthread_exit(p); + pthread_cleanup_pop(0); +} + +void *clear_task(void *args) +{ + char *msg = (char *)args; + printf("清退: %s\n", msg); + free(msg); +} + +int main() +{ + pthread_t tid; + char *q = NULL; + pthread_create(&tid, NULL, task1, NULL); + pthread_join(tid, (void **)&q); + printf("子线程退出结果: %s\n", q); + sleep(2); + + return 0; +} \ No newline at end of file diff --git a/day6/thread11.c b/day6/thread11.c new file mode 100644 index 0000000..21d80a7 --- /dev/null +++ b/day6/thread11.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +int global_data; +void clean(void *data) // 清理函数的耗时属于调用线程 +{ + printf("开始清理数据: %p\n", data); + global_data = *((int *)data); + free(data); +} + +void *task(void *data) +{ + int n = atoi((char *)data); + int *total = malloc(4); + pthread_cleanup_push(clean, total); + for (int i = 1; i <= n; i++) + { + *total += i; + usleep(200 * 1000); + } + pthread_cleanup_pop(1); + pthread_exit(NULL); // 加入清理函数后,但数据的退出无意义 +} + +typedef struct delay_cancel_info +{ + pthread_t tid; + int delay; +} DELAY_INFO; + +void *delay_cancel(void *data) +{ + DELAY_INFO *info = (DELAY_INFO *)data; + sleep(info->delay); + printf("%ld 线程即将取消\n", info->tid); + pthread_cancel(info->tid); +} + +int main(int argc, char const *argv[]) +{ + if (argc != 3) + { + printf("usage: %s number delay_time\n", argv[0]); + return 0; + } + + pthread_t tid; + pthread_create(&tid, NULL, task, (void *)argv[1]); + + DELAY_INFO info = {tid, atoi(argv[2])}; + pthread_t tid2; + pthread_create(&tid2, NULL, delay_cancel, &info); + + if (pthread_join(tid, NULL) == 0) + { + printf("%ld 子线程返回数据: %d\n", tid, global_data); + } + + return 0; +} + +/* +【小结】在线程加入的清理函数时,原线程中的pthread_exit()则不能正常返回数据。因此,在清理函数内,将当前堆的数据赋值给全局变量,在主线程中进行使用。 +*/ diff --git a/day6/thread12.c b/day6/thread12.c new file mode 100644 index 0000000..ab94948 --- /dev/null +++ b/day6/thread12.c @@ -0,0 +1,71 @@ +#include +#include +#include + +void clean(void *data) +{ + printf("---已清理---\n"); +} + +void *read_line(void *path) +{ + pthread_cleanup_push(clean, NULL); // 注册清理函数 + printf("按行读取 %s 数据\n", (char *)path); + sleep(2); + pthread_cleanup_pop(1); // 执行清理函数 +} + +int main(int argc, char const **argv) +{ + if (argc != 3) + { + printf("usage: %s filepath1 filepath2", argv[0]); + return 0; + } + + pthread_attr_t attr; // 线程属性 + pthread_attr_init(&attr); // 初始化线程属性 + // 设置线程分离 (通过属性修改) + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + // 获取当前线程的栈的大小 + size_t stackSize; + pthread_attr_getstacksize(&attr, &stackSize); + printf("线程默认的栈大小: %ld Mb\n", stackSize / 1024 / 1024); + stackSize /= 2; + pthread_attr_setstacksize(&attr, stackSize); + pthread_attr_getstacksize(&attr, &stackSize); + printf("修改后栈大小: %ld Mb\n", stackSize / 1024 / 1024); + + // 获取当前线程的优先级 + struct sched_param param; + pthread_attr_getschedparam(&attr, ¶m); + printf("默认线程的优先级: %d\n", param.__sched_priority); + + pthread_t tid2; + pthread_create(&tid2, &attr, read_line, (void *)argv[2]); + + pthread_t tid; + pthread_create(&tid, &attr, read_line, (void *)argv[1]); // 创建线程 + + param.__sched_priority = 10; + // 设置单个线程的优先级 + pthread_setschedparam(tid, SCHED_FIFO, ¶m); + struct sched_param param2; + param2.__sched_priority = 12; + pthread_setschedparam(tid2, SCHED_FIFO, ¶m2); + + int detachstate; + if (pthread_attr_getdetachstate(&attr, &detachstate) == 0) // 获取线程的分离状态 + { + if (detachstate != PTHREAD_CREATE_DETACHED) // 如果线程不是分离状态 + { + pthread_join(tid, NULL); // 等待线程结束 + } + } + + sleep(3); + pthread_attr_destroy(&attr); // 清理线程属性 + + return 0; +} diff --git a/day6/thread2.c b/day6/thread2.c new file mode 100644 index 0000000..e8fb3c0 --- /dev/null +++ b/day6/thread2.c @@ -0,0 +1,21 @@ +#include +#include +#include + +void *task1(void *data) +{ + printf("当前线程号(%ld): %s\n", pthread_self(), (char *)data); + // return NULL; + getchar(); +} + +int main() +{ + pthread_t tid; + // 子线程成功之后,则会自动启动线程 + int ret = pthread_create(&tid, NULL, task1, "hello"); + printf("主线程(%ld)退出\n", pthread_self()); + // sleep(3); + getchar(); + return 0; +} \ No newline at end of file diff --git a/day6/thread3.c b/day6/thread3.c new file mode 100644 index 0000000..b974809 --- /dev/null +++ b/day6/thread3.c @@ -0,0 +1,37 @@ +#include +#include +#include + +int n; + +void *task1(void *data) +{ + n += *((int *)data); + printf("子线程(%ld) n=%d\n", pthread_self(), n); + getchar(); +} + +int main() +{ + pthread_t tid1, tid2; + // 子线程成功之后,则会自动启动线程 + int m = 90; + int ret1 = pthread_create(&tid1, NULL, task1, &m); + if (ret1 != 0) + { + perror("pthread_create"); + } + + int m2 = 100; + int ret2 = pthread_create(&tid2, NULL, task1, &m2); + if (ret2 != 0) + { + perror("pthread_create"); + } + + printf("主线程(%ld)退出 n=%d\n", pthread_self(), n); + + // sleep(3); + getchar(); + return 0; +} \ No newline at end of file diff --git a/day6/thread4.c b/day6/thread4.c new file mode 100644 index 0000000..941bd13 --- /dev/null +++ b/day6/thread4.c @@ -0,0 +1,40 @@ +#include +#include +#include + +void *thread_task(void *data) +{ + int *arr = (int *)data; + int total = 0; + for (int i = arr[0]; i <= arr[1]; i++) + { + total += i; + } + int *result = malloc(sizeof(int)); + *result = total; + return result; +} + +int main() +{ + pthread_t tid; + int arr[2] = {1, 100}; + if (pthread_create(&tid, NULL, thread_task, arr) != 0) + { + perror("pthread_create"); + return 1; + } + + int *task_result; + // pthread_join函数等待子线程执行完毕,并将子线程的返回值存储在task_result指针中。注意,这里需要将task_result的类型为int*的指针的地址传递给pthread_join函数。 + if (pthread_join(tid, (void **)&task_result) != 0) + { + perror("pthread_join"); + return 1; + } + + printf("线程返回的结果是: %d\n", *task_result); + free(task_result); + + return 0; +} diff --git a/day6/thread6.c b/day6/thread6.c new file mode 100644 index 0000000..a19850e --- /dev/null +++ b/day6/thread6.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +// pthread_detach 的使用 +void *task1(void *data) +{ + // 提供一个整数值,计算它的阶乘 + int n = *((int *)data); + int *ret = (int *)malloc(sizeof(int)); + *ret = 1; + while (n) + { + *ret *= n--; + } + + printf("%d\n", *ret); + return NULL; +} + +int main(int argc, char const *argv[]) +{ + if (argc != 2) + { + printf("usage: ./%s 数字\n", argv[0]); + } + + pthread_t tid; + int num = atoi(argv[1]); + pthread_create(&tid, NULL, task1, (void *)&num); + // detach 分离的线程不能再由此程序处理,归由系统管理 + pthread_detach(tid); + sleep(0.5); + + return 0; +} \ No newline at end of file diff --git a/day6/thread7.c b/day6/thread7.c new file mode 100644 index 0000000..5977714 --- /dev/null +++ b/day6/thread7.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +// pthread_detach 的使用 +void *task1(void *data) +{ + // 提供一个整数值,计算它的阶乘 + int n = *((int *)data); + int *ret = (int *)malloc(sizeof(int)); + *ret = 1; + while (n) + { + *ret *= n--; + } + + pthread_exit(ret); +} + +int main(int argc, char const *argv[]) +{ + if (argc != 3) + { + printf("usage: ./%s 数字1 数字2\n", argv[0]); + } + + pthread_t tid, tid2; + int num = atoi(argv[1]); + pthread_create(&tid, NULL, task1, (void *)&num); + + int *ret = (int *)malloc(sizeof(int)); + pthread_join(tid, (void **)&ret); + + int num2 = atoi(argv[2]); + pthread_create(&tid, NULL, task1, (void *)&num2); + + int *ret2 = (int *)malloc(sizeof(int)); + pthread_join(tid, (void **)&ret2); + + printf("%d!*%d! = %d\n", num, num2, (*ret) * (*ret2)); + + sleep(0.5); + + return 0; +} \ No newline at end of file diff --git a/day6/thread7_2.c b/day6/thread7_2.c new file mode 100644 index 0000000..0b160e7 --- /dev/null +++ b/day6/thread7_2.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +void *task1(void *data) +{ + int n = *((int *)data); + int ret = 1; + while (n) + { + ret *= n--; + } + // pthread_exit(&ret); + return ret; +} + +int main(int argc, char const *argv[]) +{ + if (argc != 2) + { + printf("usage: ./%s 数字\n", argv[0]); + return 1; + } + + pthread_t tid; + int num = atoi(argv[1]); + pthread_create(&tid, NULL, task1, (void *)&num); + + int res; + pthread_join(tid, &res); + printf("%d\n", res); + + return 0; +} diff --git a/day6/thread8.c b/day6/thread8.c new file mode 100644 index 0000000..72fa1c4 --- /dev/null +++ b/day6/thread8.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +// pthread_cancel 示例 +int isCancel = 0; + +void *show(void *data) +{ + for (int i = 0; i < 100; i++) + { + printf("线程(%ld): i=%d\n", pthread_self(), i); + sleep(1); + if (isCancel) + { + printf("%ld 被取消\n", pthread_self()); + break; + + // pthread_cancel(pthread_self()); // 取消线程 + } + } + pthread_exit(NULL); +} + +void *watch_task(void *data) +{ + while (1) + { + char n = getchar(); + if (n == '1') + { + isCancel = 1; + break; + } + } + return NULL; +} + +int main(int argc, char const *argv[]) +{ + pthread_t tid, tid2; + pthread_create(&tid, NULL, show, NULL); + pthread_create(&tid2, NULL, watch_task, NULL); + + pthread_join(tid, NULL); + pthread_join(tid2, NULL); + + return 0; +} diff --git a/day6/thread8_2.c b/day6/thread8_2.c new file mode 100644 index 0000000..e2663b6 --- /dev/null +++ b/day6/thread8_2.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +// pthread_cancel 示例 2 +void *show(void *data) +{ + for (int i = 0; i < 100; i++) + { + printf("线程(%ld): i=%d\n", pthread_self(), i); + sleep(1); + } + pthread_exit(NULL); +} + +void *watch_task(void *data) +{ + pthread_t brother_th = *((pthread_t *)data); + while (1) + { + char n = getchar(); + if (n == '1') + { + printf("取消兄弟 %ld 线程\n", brother_th); + pthread_cancel(brother_th); // 根据传入的兄弟线程号取消兄弟线程 + + break; + } + } + return NULL; +} + +int main(int argc, char const *argv[]) +{ + pthread_t tid, tid2; + pthread_create(&tid, NULL, show, NULL); + pthread_create(&tid2, NULL, watch_task, &tid); // 将兄弟线程号传递过去 + + pthread_join(tid, NULL); + pthread_join(tid2, NULL); + + return 0; +} diff --git a/day6/thread9.c b/day6/thread9.c new file mode 100644 index 0000000..f0a94d8 --- /dev/null +++ b/day6/thread9.c @@ -0,0 +1,49 @@ +#include +#include +#include + +void *task1(void *data) +{ + for (int i = 0; i < 10; i++) + { + printf("%ld 子线程执行了 %d 次\n", pthread_self(), i + 1); + sleep(1); + } + return NULL; +} + +void *task2(void *data) +{ + for (int i = 0; i < 100; i++) + { + if (i % 2 == 0) + printf("%ld 子线程, 偶数 %d 次\n", pthread_self(), i); + sleep(1); + } + return NULL; +} + +void *clear(void *args) +{ + char *msg = (char *)args; + printf("清退: %s\n", msg); +} + +int main() +{ + pthread_t tid, tid2; + + pthread_create(&tid, NULL, task1, NULL); + pthread_create(&tid2, NULL, task2, NULL); + + pthread_cleanup_push(clear, "task1"); + pthread_cleanup_push(clear, "task2"); + + pthread_join(tid2, NULL); + pthread_cleanup_pop(1); + + pthread_join(tid, NULL); + pthread_cleanup_pop(1); + + return 0; +} \ No newline at end of file