💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Pthreads,第 1 部分:简介 > 原文:<https://github.com/angrave/SystemProgramming/wiki/Pthreads%2C-Part-1%3A-Introduction> ## 线程简介 ## 什么是线程? 线程是“执行线程”的缩写。它表示 CPU 具有(并将执行)的指令序列。要记住如何从函数调用返回,并存储自动变量和参数的值,线程使用栈。 ## 什么是轻量级过程(LWP)?它与线程有什么关系? 好吧,对于所有意图和目的,线程是一个过程(意味着创建一个线程类似于`fork`),除了**没有复制**意味着没有写入副本。这允许进程共享相同的地址空间,变量,堆,文件描述符等。 创建线程的实际系统调用类似于`fork`;这是`clone`。我们不会详细说明,但您可以阅读[手册页](http://man7.org/linux/man-pages/man2/clone.2.html),请记住它不在本课程的直接范围内。 LWP 或线程更倾向于分配许多场景,因为创建它们的开销要少得多。但在某些情况下(特别是 python 使用它)多处理是使代码更快的方法。 ## 线程的栈如何工作? 您的主要功能(以及您可能调用的其他功能)具有自动变量。我们将使用栈将它们存储在内存中,并使用简单的指针(“栈指针”)跟踪栈的大小。如果线程调用另一个函数,我们将栈指针向下移动,这样我们就有更多的空间用于参数和自动变量。一旦从函数返回,我们就可以将栈指针移回其先前的值。我们保留旧栈指针值的副本 - 在栈上!这就是为什么从函数返回非常快 - 很容易“释放”自动变量使用的内存 - 我们只需要更改栈指针。 ![](https://img.kancloud.cn/8d/0f/8d0fbbc8fef15386075590882d286dad_271x306.jpg) 在多线程程序中,有多个栈但只有一个地址空间。 pthread 库分配一些栈空间(在堆中或使用主程序栈的一部分)并使用`clone`函数调用在该栈地址处启动线程。总地址空间可能看起来像这样。 ![](https://img.kancloud.cn/fc/b5/fcb5f793a316935114936560fdefb88a_459x391.jpg) ## 我的进程可以有多少个线程? 您可以在进程内运行多个线程。你免费得到第一个帖子!它运行你在'main'中编写的代码。如果需要更多线程,可以使用 pthread 库调用`pthread_create`创建新线程。您需要将指针传递给函数,以便线程知道从哪里开始。 您创建的线程都存在于同一个虚拟内存中,因为它们是同一进程的一部分。因此,他们都可以看到堆,全局变量和程序代码等。因此,您可以在同一个进程内同时处理两个(或多个)CPU。由操作系统决定将线程分配给 CPU。如果你有比 CPU 更多的活动线程,那么内核会将线程分配给 CPU 很短的时间(或直到它用完了要做的事情),然后自动切换 CPU 在另一个线程上工作。例如,一个 CPU 可能正在处理游戏 AI 而另一个线程正在计算图形输出。 ## 简单用法 ## 你好世界 pthread 的例子 要使用 pthread,您需要包含`pthread.h`并且需要使用`-pthread`(或`-lpthread`)编译器选项进行编译。此选项告诉编译器您的程序需要线程支持 要创建线程,请使用函数`pthread_create`。这个函数有四个参数: ```c int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); ``` * 第一个是指向一个变量的指针,该变量将保存新创建的线程的 id。 * 第二个是指向属性的指针,我们可以使用它来调整和调整 pthreads 的一些高级功能。 * 第三个是指向我们想要运行的函数的指针 * 第四个是指向我们的函数的指针 论点`void *(*start_routine) (void *)`很难读懂!它表示一个指针,它接受一个`void *`指针并返回一个`void *`指针。它看起来像一个函数声明,除了函数的名称用`(* .... )`包装 这是最简单的例子: ```c #include <stdio.h> #include <pthread.h> // remember to set compilation option -pthread void *busy(void *ptr) { // ptr will point to "Hi" puts("Hello World"); return NULL; } int main() { pthread_t id; pthread_create(&id, NULL, busy, "Hi"); while (1) {} // Loop forever } ``` 如果我们想等待我们的线程完成使用`pthread_join` ```c void *result; pthread_join(id, &result); ``` 在上面的例子中,`result`将是`null`,因为 busy 函数返回`null`。我们需要传递结果地址,因为`pthread_join`将写入指针的内容。 见 [Pthreads 第 2 部分](https://github.com/angrave/SystemProgramming/wiki/Pthreads%2C-Part-2%3A-Usage-in-Practice)