5.2 向线程传递参数

        pthread_create()允许编程人员向线程的执行方法中传入一个参数,对于需要传递多个参数的情况,可以将这些参数封装到一个结构体中,然后将结构体对象的指针作为参数进行传入。传入的参数必须为(void *)类型。

        问题:考虑到线程启动和调度的不确定性,如何将参数安全地传递给创建的线程?

        回答:确保传入的参数都是线程安全的——这意味着它不能被其他线程修改。下面的三个例子说明了正确和错误的做法。

示例1

        这段代码展示了如何向线程中传递一个整数。主线程中每个子线程使用独有的一份数据内存进行传输,确保每个线程参数在传递过程中互不干扰。

/******************************************************************************
* FILE: hello_arg1.c
* DESCRIPTION:
*   A "hello world" Pthreads program which demonstrates one safe way
*   to pass arguments to threads during thread creation.
* AUTHOR: Blaise Barney
* LAST REVISED: 08/04/15
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS	8char *messages[NUM_THREADS];void *PrintHello(void *threadid)
{long taskid;sleep(1);taskid = (long) threadid;printf("Thread %d: %s\n", taskid, messages[taskid]);pthread_exit(NULL);
}int main(int argc, char *argv[])
{pthread_t threads[NUM_THREADS];long taskids[NUM_THREADS];int rc, t;messages[0] = "English: Hello World!";messages[1] = "French: Bonjour, le monde!";messages[2] = "Spanish: Hola al mundo";messages[3] = "Klingon: Nuq neH!";messages[4] = "German: Guten Tag, Welt!"; messages[5] = "Russian: Zdravstvuyte, mir!";messages[6] = "Japan: Sekai e konnichiwa!";messages[7] = "Latin: Orbis, te saluto!";for(t=0;t<NUM_THREADS;t++) {taskids[t] = t;printf("Creating thread %d\n", t);rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]);if (rc) {printf("ERROR; return code from pthread_create() is %d\n", rc);exit(-1);}}pthread_exit(NULL);
}

        代码输出如下

Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Creating thread 4
Creating thread 5
Creating thread 6
Creating thread 7
Thread 0: English: Hello World!
Thread 1: French: Bonjour, le monde!
Thread 2: Spanish: Hola al mundo
Thread 3: Klingon: Nuq neH!
Thread 4: German: Guten Tag, Welt!
Thread 5: Russian: Zdravstvytye, mir!
Thread 6: Japan: Sekai e konnichiwa!
Thread 7: Latin: Orbis, te saluto!

示例2

        这个例程展示了如何通过结构体设置/传递多个参数,每个线程接收独有的结构体对象。

char *messages[NUM_THREADS];struct thread_data
{
int	thread_id;
int  sum;
char *message;
};struct thread_data thread_data_array[NUM_THREADS];void *PrintHello(void *threadarg)
{int taskid, sum;char *hello_msg;struct thread_data *my_data;sleep(1);my_data = (struct thread_data *) threadarg;taskid = my_data->thread_id;sum = my_data->sum;hello_msg = my_data->message;printf("Thread %d: %s  Sum=%d\n", taskid, hello_msg, sum);pthread_exit(NULL);
}int main(int argc, char *argv[])
{pthread_t threads[NUM_THREADS];int *taskids[NUM_THREADS];int rc, t, sum;sum=0;messages[0] = "English: Hello World!";messages[1] = "French: Bonjour, le monde!";messages[2] = "Spanish: Hola al mundo";messages[3] = "Klingon: Nuq neH!";messages[4] = "German: Guten Tag, Welt!"; messages[5] = "Russian: Zdravstvytye, mir!";messages[6] = "Japan: Sekai e konnichiwa!";messages[7] = "Latin: Orbis, te saluto!";for(t=0;t<NUM_THREADS;t++) {sum = sum + t;thread_data_array[t].thread_id = t;thread_data_array[t].sum = sum;thread_data_array[t].message = messages[t];printf("Creating thread %d\n", t);rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &thread_data_array[t]);if (rc) {printf("ERROR; return code from pthread_create() is %d\n", rc);exit(-1);}}pthread_exit(NULL);
}

        输出信息如下

Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Creating thread 4
Creating thread 5
Creating thread 6
Creating thread 7
Thread 0: English: Hello World!  Sum=0
Thread 1: French: Bonjour, le monde!  Sum=1
Thread 2: Spanish: Hola al mundo  Sum=3
Thread 3: Klingon: Nuq neH!  Sum=6
Thread 4: German: Guten Tag, Welt!  Sum=10
Thread 5: Russian: Zdravstvytye, mir!  Sum=15
Thread 6: Japan: Sekai e konnichiwa!  Sum=21
Thread 7: Latin: Orbis, te saluto!  Sum=28

示例3

        这个例程中进行了错误的参数传递,它把所有线程都能访问的共享内存中的变量t的地址传递给了各个线程。随着循环的进行,t的值可能会发生预料外的改变,从而对使用它的线程产生影响。

/*****************************************************************************
* FILE: hello_arg3.c
* DESCRIPTION:
*   This "hello world" Pthreads program demonstrates an unsafe (incorrect)
*   way to pass thread arguments at thread creation.  In this case, the
*   argument variable is changed by the main thread as it creates new threads.
* AUTHOR: Blaise Barney
* LAST REVISED: 07/16/14
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS     8void *PrintHello(void *threadid)
{long taskid;sleep(1);taskid = *(long *)threadid;printf("Hello from thread %ld\n", taskid);pthread_exit(NULL);
}int main(int argc, char *argv[])
{pthread_t threads[NUM_THREADS];int rc;long t;for(t=0;t<NUM_THREADS;t++) {printf("Creating thread %ld\n", t);rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &t);if (rc) {printf("ERROR; return code from pthread_create() is %d\n", rc);exit(-1);}}pthread_exit(NULL);
}

        输出信息如下。

Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Creating thread 4
Creating thread 5
Creating thread 6
Creating thread 7
Hello from thread 140737488348392
Hello from thread 140737488348392
Hello from thread 140737488348392
Hello from thread 140737488348392
Hello from thread 140737488348392
Hello from thread 140737488348392
Hello from thread 140737488348392
Hello from thread 140737488348392

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/131268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python库学习(十二):数据分析Pandas[下篇]

接着上篇《Python库学习(十一):数据分析Pandas[上篇]》,继续学习Pandas 1.数据过滤 在数据处理中&#xff0c;我们经常会对数据进行过滤&#xff0c;为此Pandas中提供mask()和where()两个函数&#xff1b; mask(): 在 满足条件的情况下替换数据&#xff0c;而不满足条件的部分…

leetcode-经典面/笔试题目

1.消失的数字 面试题 17.04. 消失的数字 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/missing-number-lcci/ 这个题目当然有好几种解法&#xff0c;这里我推荐一种比较优秀的思路&#xff0c;也就是单身狗思路&#xff1a;异或。 异或的特点是相异…

账户权限控制

1.首先配置一个单群组4节点的链 1.1创建操作目录 cd ~ && mkdir -p fisco && cd fisco 1.2下载国内脚本 curl -#LO https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/FISCO-BCOS/FISCO-BCOS/releases/v2.9.1/build_chain.sh && chmod ux bu…

【KVM】软件虚拟化和硬件虚拟化类型

前言 大家好&#xff0c;我是秋意零。 今天介绍的内容是虚拟化技术以及软件虚拟化和硬件虚拟化。 &#x1f47f; 简介 &#x1f3e0; 个人主页&#xff1a; 秋意零&#x1f525; 账号&#xff1a;全平台同名&#xff0c; 秋意零 账号创作者、 云社区 创建者&#x1f9d1; 个…

Linux 之搭建 arm 的 qemu 模拟器

目录 1. Linux 之搭建 arm 的 qemu 模拟器 1. Linux 之搭建 arm 的 qemu 模拟器 OS: kali 1. 安装交叉编译工具、GDB 和 QEMU # sudo apt-get install qemu debootstrap qemu-user-static # sudo apt-get install qemu-system-arm # sudo apt-get install gdb-multiarch //支持…

系统提示缺少或找不到d3dcompiler_43.dll文件的详细修复教程

今天我来给大家分享一下关于d3dcompiler_43.dll缺失的4个修复方法。 首先&#xff0c;我们来了解一下d3dcompiler_43.dll的作用。它是DirectX中的一个组件&#xff0c;用于编译Shader和Pixel着色器代码。如果缺少了这个文件&#xff0c;就会导致游戏或应用程序无法正常运行。 …

全能数据分析软件 Tableau Desktop 2019 mac中文版功能亮点

Tableau Desktop 2019 mac是一款专业的全能数据分析工具&#xff0c;可以让用户将海量数据导入并记性汇总&#xff0c;并且支持多种数据类型&#xff0c;比如像是编程常用的键值对、哈希MAP、JSON类型数据等&#xff0c;因此用户可以将很多常用数据库文件直接导入Tableau Deskt…

适合新手自学的网络安全基础技能“蓝宝书”:《CTF那些事儿》

文章目录 内容简介读者对象专家推荐目录赠书活动 CTF比赛是快速提升网络安全实战技能的重要途径&#xff0c;已成为各个行业选拔网络安全人才的通用方法。但是&#xff0c;本书作者在从事CTF培训的过程中&#xff0c;发现存在几个突出的问题&#xff1a; 线下CTF比赛培训中存在…

Docker / OSX快速入门

Docker / OSX快速入门 目录 Docker / OSX快速入门 在Mac上安装 Boot2Docker 关于容器的一个注意事项 一个例子&#xff1a;Python Flask App 运行 在AWS上运行相同的容器 更多东西 本文章向大家介绍Docker / OSX快速入门&#xff0c;主要内容包括在Mac上安装、Boot2Do…

C++11范围for

在C98中&#xff0c;不同的STL容器和C风格数组的遍历方式各不相同&#xff0c;写法也不统一&#xff0c;而且不够简洁。而C11基于范围的for循环可以简洁并且统一的方式遍历STL容器和C风格数组。 在介绍for循环新的语法之前&#xff0c;简单来看一下for循环之前遍历STL容器的例…

力扣:149. 直线上最多的点数(Python3)

题目&#xff1a; 给你一个数组 points &#xff0c;其中 points[i] [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱…

stm32整理(三)ADC

1 ADC简介 1.1 ADC 简介 12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道&#xff0c;可测量来自 16 个外部 源、两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续 采样模式下进行。ADC 的结果存储在一个左对齐或右对齐的 16 位…

农业中的机器学习

机器学习训练模型推荐&#xff1a; UnrealSynth虚幻合成数据生成器 - NSDT 机器学习是一个不断发展的领域&#xff0c;在农业中有许多潜在的应用。农民和农业科学家正在探索如何转向机器学习开发来提高作物产量、减少用水量和预测病虫害。未来&#xff0c;机器学习可以帮助农民…

相对位置编码RPE:桶的数量

在相对位置编码中&#xff0c;"桶"指的是一种将不同的相对位置映射到一个有限数量的离散区间的方式。这个离散区间的数量通常由"桶的数量"来表示。在编码相对位置时&#xff0c;相对位置的值会被分配到不同的桶中&#xff0c;以便在有限的编码空间中表示无…

Proteus仿真--12864LCD显示计算器键盘按键实验(仿真文件+程序)

本文主要介绍基于51单片机的12864LCD液晶显示电话拨号键盘按键实验&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 本设计主要介绍计算器键盘仿真&#xff0c;按键按下后在12864液晶上显示对应按键键值 仿真运行视频 Proteus仿真--12864LCD显示计算器…

设计模式_访问者模式

访问者模式 介绍 设计模式定义案例问题堆积在哪里访问模式访问模式是行为型设计模式 从对象中分类出算法 这些算法封装为对象&#xff0c; 这样这些算法类很容易扩展&#xff0c;添加新的算法类就可以了不同的VIP用户 在不同的节日 领取不同的礼物if else太多 解决办法小技巧…

[自定义 Vue 组件] 小尾巴顶部导航栏(2.0) TailTopNav

文章归档&#xff1a;https://www.yuque.com/u27599042/coding_star/oglrqteg8fzvvzn0 [自定义 Vue 组件] 响应式顶部导航栏(1.0) TopNav&#xff1a;https://www.yuque.com/u27599042/coding_star/hzltsltxgavwx8u2 组件效果示例 组件所依赖的子组件 [自定义 Vue 组件] 小尾巴…

STM32F103C8T6第一天:认识STM32 标准库与HAL库 GPIO口 推挽输出与开漏输出

1. 课程概述&#xff08;297.1&#xff09; 课程要求&#xff1a;C语言熟练&#xff0c;提前学完 C51 2. 开发软件Keil5的安装&#xff08;298.2&#xff09; 开发环境的安装 编程语言&#xff1a;C语言需要安装的软件有两个&#xff1a;Keil5 和 STM32CubeMX Keil5 的安装…

读书笔记:彼得·德鲁克《认识管理》第3章 西尔斯公司

一、章节内容概述 与其他美国大型企业相比&#xff0c;西尔斯公司的成就更加令人瞩目、更加长盛不衰。然而&#xff0c;当没有任何邮购经验的芝加哥服装商人罗森沃尔德 1895年进行收购时&#xff0c;该公司已濒临破产。罗森沃尔德深入思考了公司的 业务&#xff0c;并询问下列…

android display 杂谈(三)WMS

用来记录学习wms&#xff0c;后续会一点一点更新。。。。。。 代码&#xff1a;android14 WMS是在SystemServer进程中启动的 在SystemServer中的main方法中&#xff0c;调用run方法。 private void run() { // Initialize native services.初始化服务&#xff0c;加载andro…