首页 > 编程语言 >c++如何使用pthread_join函数配合pthread_create函数来创建和等待线程完成,实现线程同步与控制

c++如何使用pthread_join函数配合pthread_create函数来创建和等待线程完成,实现线程同步与控制

时间:2024-10-15 23:12:18浏览次数:1  
标签:join 函数 Thread create 线程 pthread

在C++中,pthread_create 和 pthread_join 是 POSIX 线程库(pthread)的一部分,用于创建和管理线程。pthread_create 用于创建一个新的线程,而 pthread_join 用于等待一个线程的执行完成,从而实现线程同步与控制。

基本步骤

  1. 使用 pthread_create 函数创建一个线程。
  2. 线程的工作由一个线程函数来完成,该函数的签名必须是 void* threadFunc(void* arg)
  3. 使用 pthread_join 函数等待线程执行完成,并获取线程的退出状态。

以下是如何在C++中使用 pthread_create 和 pthread_join 来创建线程并等待其完成的示例:

示例代码

#include <iostream>
#include <pthread.h>  // POSIX 线程库头文件
#include <unistd.h>   // sleep 函数

// 线程执行的函数
void* threadFunc(void* arg) {
    int* id = static_cast<int*>(arg);  // 传入的参数类型转换
    std::cout << "Thread " << *id << " is running." << std::endl;
    sleep(2);  // 模拟线程工作
    std::cout << "Thread " << *id << " has finished." << std::endl;
    return nullptr;
}

int main() {
    const int numThreads = 3;
    pthread_t threads[numThreads];  // 保存线程ID
    int threadArgs[numThreads];     // 线程的参数

    // 创建多个线程
    for (int i = 0; i < numThreads; ++i) {
        threadArgs[i] = i + 1;  // 为每个线程传递不同的参数
        if (pthread_create(&threads[i], nullptr, threadFunc, &threadArgs[i]) != 0) {
            std::cerr << "Error creating thread " << i + 1 << std::endl;
            return 1;
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < numThreads; ++i) {
        if (pthread_join(threads[i], nullptr) != 0) {
            std::cerr << "Error joining thread " << i + 1 << std::endl;
            return 1;
        }
        std::cout << "Thread " << i + 1 << " has joined." << std::endl;
    }

    std::cout << "All threads have completed." << std::endl;
    return 0;
}

代码解析

  1. pthread_create:

    • 创建线程时使用 pthread_create,第一个参数是线程ID的指针,第二个参数是线程的属性(可以传入nullptr使用默认属性),第三个参数是线程函数的地址,第四个参数是传递给线程函数的参数。
    • 每个线程会执行 threadFunc 函数,并接收不同的 threadArgs 作为参数。
  2. pthread_join:

    • 主线程使用 pthread_join 来等待子线程完成执行。pthread_join 的第一个参数是线程ID,第二个参数用于获取线程的返回值(我们这里传入nullptr表示不关心返回值)。
    • pthread_join 可以保证主线程等待所有子线程执行完成后再继续执行。
  3. threadFunc:

    • 这是子线程执行的函数。它的参数是 void* 类型,所以我们需要将其转换为适当的类型(在此例中是 int*)。
    • 模拟线程任务时使用 sleep(2) 让线程休眠2秒。
  4. 线程参数:

    • 为了避免多个线程共享同一个参数导致的问题,我们为每个线程分配一个单独的参数 threadArgs[i]

输出示例

Thread 1 is running.
Thread 2 is running.
Thread 3 is running.
Thread 1 has finished.
Thread 1 has joined.
Thread 2 has finished.
Thread 2 has joined.
Thread 3 has finished.
Thread 3 has joined.
All threads have completed.

线程同步与控制

通过使用 pthread_join,我们可以确保主线程在所有子线程执行完成之后才继续执行,这样可以避免主线程提前退出而导致子线程未完成的问题。这也是一种常见的线程同步机制。

注意事项

  1. 数据竞争: 如果多个线程同时访问共享资源而不使用同步机制(如互斥锁 pthread_mutex_t),可能会导致数据竞争。
  2. 线程返回值: 如果需要获取线程的返回值,可以在 pthread_join 的第二个参数中提供指针接收线程函数的返回值。
  3. 线程的可重入性: 如果线程之间共享数据,应确保线程安全,避免数据竞争或不一致的状态。

通过以上代码示例,你可以理解如何使用 pthread_create 和 pthread_join 来实现多线程的同步与控制。

标签:join,函数,Thread,create,线程,pthread
From: https://www.cnblogs.com/chentiao/p/18468749

相关文章

  • C++中的回调函数
    回调函数(callbackfunction)是指作为参数传递给另一个函数的函数,在某个事件发生或某个任务完成时被调用。回调函数在异步编程中非常常见,因为它们允许代码在某个操作完成后自动执行某些行为,而无需阻塞程序。回调函数的基本特征作为参数传递:回调函数通常是作为参数传递给另一个函......
  • 第九章习题3-编写一个函数print,打印一个学生的成绩数组,该数组有5个学生的数据记录,每个
     ......
  • C++中的不安全函数
    不安全函数(UnsafeFunctions)通常指那些在特定条件下可能导致程序错误、数据损坏或安全漏洞的函数。在编程中,不安全函数可能表现为以下几种情况:缓冲区溢出:当函数在处理数据时没有检查输入的大小,可能导致超出预分配内存空间的写入,造成数据破坏或程序崩溃。例如,在C和C++中,strcpy、......
  • 函数
    Rust代码中的函数和变量名使用snakecase规范风格。在snakecase中,所有字母都是小写并使用下划线分隔单词。这是一个包含函数定义示例的程序:fnmain(){println!("Hello,world!");another_function();}fnanother_function(){println!("Anotherfuncti......
  • 线程,进程,协程
    线程,进程,协程进程是什么:​ 最小的资源分配单位。进程上下文切换​ 指cpu保持原有的进程的状态的同时去切换到下一个进程​ 包含两个主要过程:进程地址空间切换和处理器状态切换线程是什么​ 线程是操作系统中最小的调度单位。​ 线程是进程的子集,也称为轻量级进程。一......
  • 【多线程奇妙屋】“线程等待” 专讲,可不要只会 join 来线程等待哦, 建议收藏 ~~~
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • Java中多线程的学习
    Java多线程学习总结目录Java多线程学习总结什么是进程什么是线程进程与线程的区别地址空间资源占用健壮性执行过程并发与资源消耗创建线程方式一:继承Thread类,并重写run()方法方式二:实现Runnable接口,并实现run()方法线程的状态线程暂停执行条件线程优先级多线程多线......
  • Python学习流水账Day5——有关Python中的函数
    文章目录前言一、Python中的函数1.内置函数2.定义一个函数调用函数为函数设置参数实参形参给函数设置多个形参默认形参函数的返回值函数的变量局部变量全局变量3.匿名函数4.递归函数总结前言简单的python复习第五天:不是用来教学的,上班没劲,主打一个本科毕业没竞......
  • C++的仿函数functor
    C++的仿函数functor详细内容仿函数(Functor)是C++中的一种设计模式,也叫函数对象。仿函数是一个重载了operator()的类或结构体,它可以像普通函数一样被调用。这使得它具有类似函数的行为,但实际上它是一个对象,因此可以拥有状态(成员变量)和更多的灵活性。仿函数的主要用途是:可以......
  • java爬虫多线程代理:为数据采集提供强力支持
    Java爬虫中的多线程与代理应用在当今这个信息爆炸的时代,数据的获取与处理变得尤为重要。Java作为一种强大的编程语言,广泛应用于爬虫开发中。而在爬虫的实践中,多线程和代理的结合,可以让我们的爬虫如同一支训练有素的队伍,快速、高效地获取所需数据。接下来,我们将深入探讨Java爬......