线程与线程:从入门到放弃

news/2025/2/21 7:05:27

引言

在计算机科学中,**线程**是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程可以拥有多个线程,这些线程共享进程的内存空间和资源,但每个线程拥有独立的执行栈和程序计数器。

本文将带你走进线程的世界,从基础概念到实际应用,用简单的C语言代码示例,让你轻松理解线程的奥秘。

 一、线程的基本概念

1. 线程的定义:
   线程是进程中的一个执行流,每个线程都有自己的程序计数器、寄存器集合和栈。
   线程是CPU调度的基本单位。

2. 线程与进程的区别:
    进程是资源分配的基本单位,线程是CPU调度的基本单位。
   进程拥有独立的内存空间,线程共享进程的内存空间。
   进程间通信复杂,线程间通信简单。

3. **线程的优点**:
   - 创建和销毁线程的开销比进程小。
   - 线程间切换的开销比进程小。
   - 线程间通信方便,共享数据简单。

 二、C语言中的线程

在C语言中,我们可以使用`pthread`库来创建和管理线程。`pthread`是POSIX标准定义的线程库,广泛用于Unix-like系统。

1. 创建线程:
   使用`pthread_create`函数创建线程。
   函数原型:

     int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);


   参数说明:
      `thread`:指向线程标识符的指针。
      `attr`:线程属性,通常为`NULL`。
      `start_routine`:线程函数的起始地址。
     `arg`:传递给线程函数的参数。

2. 线程函数:
   - 线程函数是一个返回`void*`类型的函数,接受一个`void*`类型的参数。
   - 示例:

 void* thread_function(void* arg) {
         int thread_id = *(int*)arg;
         printf("Thread ID: %d\n", thread_id);
         pthread_exit(NULL);
     }

3. 等待线程结束:
   使用`pthread_join`函数等待线程结束。
   函数原型:

int pthread_join(pthread_t thread, void **retval);


    参数说明:
     `thread`:要等待的线程标识符。
      `retval`:指向线程返回值的指针,通常为`NULL`。

三、示例代码

下面是一个简单的C语言程序,演示了如何创建和运行线程。

#include <stdio.h>
#include <pthread.h>

#define NUM_THREADS 5

void* thread_function(void* arg) {
    int thread_id = *(int*)arg;
    printf("Thread ID: %d\n", thread_id);
    pthread_exit(NULL);
}

int main() {
    pthread_t threads[NUM_THREADS];
    int thread_args[NUM_THREADS];

    for (int i = 0; i < NUM_THREADS; i++) {
        thread_args[i] = i;
        int result = pthread_create(&threads[i], NULL, thread_function, (void*)&thread_args[i]);
        if (result != 0) {
            printf("Error creating thread %d\n", i);
            return -1;
        }
    }

    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }

    printf("All threads have completed.\n");
    return 0;
}

四、总结

通过本文的学习,你应该对线程有了基本的了解,并掌握了如何在C语言中使用`pthread`库创建和管理线程。线程是并发编程的基础,掌握线程的使用对于编写高效、并发的程序至关重要。

希望这篇文章能帮助你在CSDN上发表一篇高质量的《线程与线程》文章,祝你在编程的道路上越走越远!


http://www.niftyadmin.cn/n/5860422.html

相关文章

JUC并发—8.并发安全集合二

大纲 1.JDK 1.7的HashMap的死循环与数据丢失 2.ConcurrentHashMap的并发安全 3.ConcurrentHashMap的设计介绍 4.ConcurrentHashMap的put操作流程 5.ConcurrentHashMap的Node数组初始化 6.ConcurrentHashMap对Hash冲突的处理 7.ConcurrentHashMap的并发扩容机制 8.Concu…

第1章大型互联网公司的基础架构——1.11 消息中间件技术

消息队列&#xff08;Message Queue&#xff09;是分布式系统中最重要的中间件之一&#xff0c;在服务架构设计中被广泛使用。 1.11.1 通信模式与用途 消息中间件构建了这样的通信模式&#xff1a; 一条消息由生产者创建&#xff0c;并被投递到存放消息的队列中&#xff1b;…

使用Python和正则表达式爬取网页中的URL数据

在数据抓取和网络爬虫开发中&#xff0c;提取网页中的URL是一个常见的需求。无论是用于构建网站地图、分析链接结构&#xff0c;还是进行内容聚合&#xff0c;能够高效地从HTML文档中提取URL都是一个重要的技能。Python作为一种强大的编程语言&#xff0c;结合其正则表达式模块…

ubuntu22.04使用minikube安装k8s

ubuntu使用minikube安装k8s 准备工作安装步骤安装docker安装kubectl安装minikube导入相关镜像安装相关指令启动minikube服务 安装dashboard组件导入相关镜像创建服务账号安装组件本体验证安装结果 准备工作 下载离线安装包&#xff0c;安装包内容如下&#xff1a; 软件说明ki…

windows使用命令解压jar包,替换里面的文件。并重新打包成jar包,解决Failed to get nested archive for entry

有一个jar包&#xff0c;需要替换里面的文件&#xff0c;使用解压工具打开项目&#xff0c;然后找到对应的子包&#xff0c;再次打开&#xff0c;然后进行手工替换重新压缩成jar包后&#xff0c;发现启动服务报错Failed to get nested archive for entry。 使用下面的命令可实…

jmeter接口测试(一)

一、什么是接口测试&#xff1f;为什么要做接口测试&#xff1f; 接口测试&#xff1a;就是测试项目和项目之间&#xff0c;模块和模块之间&#xff0c;组件和组件之间的数据交互和权限鉴定&#xff08;鉴权&#xff09;。 前后端分离&#xff1a;前后端联调。mock模拟&#x…

搭建 Hadoop 3.3.6 伪分布式

搭建 Hadoop 3.3.6 伪分布式 IP 192.168.157.132 初始化操作 更改yum源 # 1_1.安装Wget yum install wget# 1_2.备份CentOS-Base.repo文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_bak# 2.下载阿里yum源配置 wget -O /etc/yum.repos.d/Cen…

元脑服务器可用于DeepSeek部署

元脑服务器系列&#xff0c;由浪潮电子信息产业股份有限公司研发并推出&#xff0c;旨在满足人工智能等高端应用领域对高性能计算的需求。以下内容将对元脑服务器进行详细阐述&#xff1a; 一、发展及定位 2024年4月17日&#xff0c;于浪潮信息生态伙伴大会上&#xff0c;“元脑…