This commit is contained in:
flykhan 2023-08-21 19:45:29 +08:00
parent 49d2f0cabb
commit 8df60e2dc6
13 changed files with 546 additions and 0 deletions

10
day6/thread1.c Normal file
View File

@ -0,0 +1,10 @@
#include <stdio.h>
#include <pthread.h>
int main()
{
printf("当前线程号: %ld", pthread_self()); // 获取当前线程号
char test_char = getchar(); //阻塞程序的执行,等待用户输入一个字符后才会继续执行后面的代码
printf("获取到 %c\n", test_char);
return 0;
}

38
day6/thread10.c Normal file
View File

@ -0,0 +1,38 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
// 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;
}

68
day6/thread11.c Normal file
View File

@ -0,0 +1,68 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
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()线使
*/

71
day6/thread12.c Normal file
View File

@ -0,0 +1,71 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
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, &param);
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, &param);
struct sched_param param2;
param2.__sched_priority = 12;
pthread_setschedparam(tid2, SCHED_FIFO, &param2);
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;
}

21
day6/thread2.c Normal file
View File

@ -0,0 +1,21 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
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;
}

37
day6/thread3.c Normal file
View File

@ -0,0 +1,37 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
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;
}

40
day6/thread4.c Normal file
View File

@ -0,0 +1,40 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
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;
}

37
day6/thread6.c Normal file
View File

@ -0,0 +1,37 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
// 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;
}

46
day6/thread7.c Normal file
View File

@ -0,0 +1,46 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
// 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;
}

35
day6/thread7_2.c Normal file
View File

@ -0,0 +1,35 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
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;
}

50
day6/thread8.c Normal file
View File

@ -0,0 +1,50 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
// 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;
}

44
day6/thread8_2.c Normal file
View File

@ -0,0 +1,44 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
// 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;
}

49
day6/thread9.c Normal file
View File

@ -0,0 +1,49 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
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;
}