本文章基于操作系统(5) (POSIX--Linux线程编程pthread_t/create/join/exit)-CSDN博客
https://blog.csdn.net/2301_80176774/article/details/143078984创作,主要讲解c语言相关语法/pthread_t/create/join应用.
目录
1. 线程与pthread库
2. 代码结构与解释
3. 结构体letter
4. 线程函数 print_letter (通过使用结构体对象地址来打印结构图属性)
5. 主函数 main
5.1 定义线程ID
5.2 设置线程参数
5.3 创建线程
5.4 等待线程结束
6. 代码执行流程
7. 多线程编程中的注意事项
8. 代码输出示例

1. 线程与pthread库
在Linux环境中,pthread(POSIX thread)库提供了强大的多线程支持。pthread库允许开发者在同一个进程内创建多个线程,从而实现并发执行。这对于需要并行处理的任务非常有用,比如在本例中并行地打印不同字符。
在使用pthread库时,需要包含pthread.h头文件,并在编译时加上-pthread选项:
gcc -o program program.c -pthread
2. 代码结构与解释
代码整体分为三部分:
- 定义数据结构(
struct letter):用于存储线程的参数。 - 线程函数(
print_letter):线程运行的函数,负责打印指定字符。 - 主函数(
main):创建并启动线程,最后等待线程结束。
3. 结构体letter
struct letter {char name;int times;
};
这个结构体letter包含两个成员:
name:字符类型,用于存储要打印的字符。times:整数类型,用于存储打印的次数。
4. 线程函数 print_letter (通过使用结构体对象地址来打印结构图属性)
void* print_letter(void* para) {struct letter* p = (struct letter*)para;for (int i = 0; i < p->times; i++) {fputc(p->name, stdout);}return NULL;
}
print_letter是一个线程函数,参数为void*类型,以便接受任意类型的输入。在函数内部,将参数para转换为letter类型的指针p,然后读取其中的字符和次数。
fputc(p->name, stdout);:将字符输出到标准输出stdout。return NULL;:返回NULL表示线程完成。
在多线程函数中,参数通常定义为void*,以支持不同类型的数据传递。需要传递自定义结构体时,通过类型转换恢复结构体类型的指针,以便访问具体数据。
5. 主函数 main
int main() {pthread_t t1_id, t2_id;struct letter l1, l2;l1.name = 'a';l2.name = 'w';l1.times = 20;l2.times = 20;pthread_create(&t1_id, NULL, &print_letter, &l1);pthread_create(&t2_id, NULL, &print_letter, &l2);pthread_join(t1_id, NULL);pthread_join(t2_id, NULL);return 0;
}
5.1 定义线程ID
pthread_t t1_id, t2_id;:pthread_t类型变量用于存储线程ID,以便稍后对线程进行操作。
5.2 设置线程参数
struct letter l1, l2;:定义两个letter结构体变量l1和l2,分别用于存储字符'a'和'w',并将打印次数设置为20。
5.3 创建线程
pthread_create(&t1_id, NULL, &print_letter, &l1);:调用pthread_create创建一个新线程。- 第一个参数
&t1_id用于存储新线程的ID。 - 第二个参数
NULL用于指定线程属性,NULL表示使用默认属性。 - 第三个参数
&print_letter是线程函数的地址。 - 第四个参数
&l1是传递给线程函数的参数,即l1结构体的地址。
- 第一个参数
- 第二个线程
pthread_create(&t2_id, NULL, &print_letter, &l2);类似。
5.4 等待线程结束
pthread_join(t1_id, NULL);:主线程调用pthread_join等待t1_id表示的线程执行完毕。pthread_join(t2_id, NULL);:同样等待t2_id表示的线程执行完毕。
通过pthread_join确保主线程在两个子线程结束后才会继续执行,以实现同步。
6. 代码执行流程
- 主线程创建两个结构体
l1和l2,分别存储要打印的字符和次数。 - 主线程使用
pthread_create启动两个子线程print_letter,每个线程负责打印特定字符。 - 两个线程执行
print_letter函数,分别打印'a'和'w',每个字符打印20次。 - 主线程通过
pthread_join等待两个子线程执行完毕,最后返回0,表示程序正常结束。
7. 多线程编程中的注意事项
- 数据同步:在多线程环境中,多个线程可能会访问相同的内存区域,导致数据竞争。虽然本代码不存在共享数据,但在实际应用中,如果多个线程操作同一数据结构,通常需要使用互斥锁(
pthread_mutex_t)来保证线程安全。 - 线程参数传递:线程函数的参数类型为
void*,这使得在传递自定义结构体时需要类型转换。传递参数时要确保结构体的内存有效,避免线程访问非法内存区域。 - 线程终止:线程函数可以返回,也可以调用
pthread_exit()来结束线程。
8. 代码输出示例
该代码执行后,输出会包含连续的字符'a'和'w'。由于多线程并发执行,输出的顺序不确定,比如可能输出:
aaaawwwwawawawawawawawawawawawawaaaawwwwwaawa
