This commit is contained in:
parent
49d2f0cabb
commit
8df60e2dc6
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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()则不能正常返回数据。因此,在清理函数内,将当前堆的数据赋值给全局变量,在主线程中进行使用。
|
||||||
|
*/
|
|
@ -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, ¶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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue