pthread_join 损坏堆栈中的 pthread_create 参数

2024-01-30

我从一本高级 Linux 编程书中得到了这段代码。当我尝试在Linux 64位环境下执行代码时,which_prime之后变量被损坏(更改为 0)pthread_join()函数调用。

在这个例子中为什么值which_prime运行 pthread_join 后损坏?

一般来说,即使我们调用其他函数,我们也可以在 main 内部安全地使用传递给 pthread_create 函数的第四个参数pthread_join()?

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

/* Compute successive prime numbers (very inefficiently). Return the
Nth prime number, where N is the value pointed to by *ARG. */
void* compute_prime (void* arg)
{
    int candidate = 2;

    int n = *((int*) arg);
    while (1) {
        int factor;
        int is_prime = 1;
        /* Test primality by successive division. */
        for (factor = 2; factor < candidate; ++factor)
            if (candidate % factor == 0) {
                is_prime = 0;
                break;
            }
        /* Is this the prime number we’re looking for? */
        if (is_prime) {
            if (--n == 0)
                /* Return the desired prime number as the thread return value. */
                return (void*) candidate;
        }
        ++candidate;
    }
    return NULL;
}

int main ()
{
    pthread_t thread;
    int which_prime = 5000;
    int prime;
    /* Start the computing thread, up to the 5,000th prime number. */
    pthread_create (&thread, NULL, &compute_prime, &which_prime);
    /* Do some other work here... */
    /* Wait for the prime number thread to complete, and get the result. */
    pthread_join (thread, (void*) &prime);
    /* Print the largest prime it computed. */
    printf(“The %dth prime number is %d.\n”, which_prime, prime);
    return 0;
}

我们已经到了一个时间点,在不同的货币之间进行转换不再安全。int and a pointer。这是因为在 64 位系统中,指针是 64 位的,但是int只有 32 位。

所以假设32位int和 64 位指针,这就是您的代码中发生的情况。第二个参数pthread_join是一个指向指针的指针。换句话说,您应该传递指针的地址(64 位值的地址)。相反,您传递的地址是prime(32 位值的地址)。什么时候pthread_join写入结果,它会覆盖which_prime, 因为which_prime如下prime在记忆中。

要解决此问题,您需要避免在之间进行转换ints 和指针。一种方法是避免使用第二个参数pthread_join,如以下代码所示。

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

#define NUM_THREADS 20

typedef struct
{
    int success;
    int input;
    int output;
} stData;

void *doSomething( void *arg )
{
    stData *dataptr = arg;

    dataptr->success = 1;
    dataptr->output  = dataptr->input * 2;
    return NULL;
}

int main( void )
{
    int i;
    pthread_t id[NUM_THREADS];
    stData data[NUM_THREADS] = {{0}};

    for ( i = 0; i < NUM_THREADS; i++ )
    {
        data[i].input = i + 1;
        pthread_create( &id[i], NULL, doSomething, &data[i] );
    }

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

        if ( data[i].success )
            printf( "thread %2d: input=%2d output=%2d\n", i+1, data[i].input, data[i].output );
        else
            printf( "thread %2d: failed\n", i+1 );
    }

    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pthread_join 损坏堆栈中的 pthread_create 参数 的相关文章

随机推荐

  • 未找到具有有效签名身份(即证书和私钥对)的配置文件

    是的 我知道这个问题有很多重复 但我尝试了其他人建议的所有内容 此时我没有重复项 我从头开始撤销并重新生成了证书和密钥 我将我的证书与相应的密钥配对 我面临的问题如下 如果我尝试在构建设置中使用发行配置文件进行发布 我会不断收到标头中指定的
  • 如何将 xml 字符串读入 XMLTextReader 类型

    我有一个 XML 字符串 我需要将此字符串转换为XML文本阅读器 System Xml XMLTextReader 输入 dotnet 我使用了以下代码 string szInputXml
  • 如何编辑 JavaScript 警报框标题?

    我正在 C NET 页面中使用以下代码生成 JavaScript 警报 Response Write 它显示一个标题为 来自网页的消息 的警告框 标题可以修改吗 不 你不能 这是一项安全 反网络钓鱼功能
  • Solr:如何搜索多个字段

    我正在使用 solrnet 我有标题和描述字段 我需要同时搜索这两个字段 我该怎么做呢 Jayendra 的答案是正确的 但如果您想在索引时 copyFields 不聚合单个字段中的数据并希望在查询时执行此操作 而不是使用标准处理程序而不是
  • 选项卡行为 Resharper Intellisense 选项

    像 Resharper 这样的产品有很多设置 但我似乎无法找到正确的设置来获得我想要的确切行为 我试图改变的行为是这样的 假设我想要的最终结果是 但目前的线路是 正如你所期望的 我开始输入 一个选项卡后我得到这个 但我希望它成为 有谁知道如
  • 批处理 - 将变量与正则表达式进行比较

    我正在编写一个批处理脚本 必须检查计算机上是否安装了某些程序 为此 我执行programName version我将输出存储在变量中 问题是当我尝试与正则表达式进行比较时 只是为了知道该程序是否存在于机器中 我正在尝试这段代码 但不起作用
  • 使用 Python 在大型文本文件中查找和替换特定行的最快方法

    我有一个numbers txt文件由多个 100K 行组成 每行由两个唯一的数字组成 并用 sign 407597693 1604722326 2426915 510905857 1604722326 2696202 76792361 16
  • 你真的需要“finally”块吗

    java 中的 try catch finally 块有 3 种排列 试着抓 尝试 抓住 终于 尝试 终于 一旦执行了finally 块 控制就会转到finally 块之后的下一行 如果我删除finally块并将其所有语句移至try cat
  • 输入一系列音符并播放它们

    我和我的儿子正在尝试编写一个程序 允许用户输入一系列音符 并将它们保存到要播放的列表中 我们提出了以下方案 import math import needed modules import pyaudio sudo apt get inst
  • node-webkit 相当于 sinatra 吗?

    我一直在考虑学习如何基于 Web 技术制作简单的 Mac OS X 应用程序 并且我遇到了似乎很有吸引力的 node webkit 然而 我最近投入了学习 Sinatra Ruby 的基础知识 并且我想继续学习该课程 对于使用 Sinatr
  • Objective C 协议相当于 Java 接口吗?

    问题不仅仅是关于标题 更多的是 我将如何实现这一目标 而不试图将 Java Flash 设计强制到 Objective C iPhone 程序中 我有 6 个扩展 UIView 的视图 这些视图都有不同的行为 但共享某些方法 例如 void
  • 在相机视图上显示自定义按钮

    有谁知道是否有一种方法可以在相机视图上粘贴自定义按钮 以允许用户像 oink 或 instagram 一样从其库中选择照片 而无需创建自定义视图 谢谢 Edit 使用覆盖层添加按钮似乎很容易 有谁知道如何实际显示照片库并使用该人选择的内容
  • KendoMobile ui 模板不渲染 css 如何使模板在视图中使用 kendo stylng 进行渲染?

    基本上模板不会使用以下方式渲染到 ScrollViewkendo render template response 但会与content template response 但这没有视图中的样式 请参阅下面的评论 如何使模板在视图中呈现剑道
  • Animate.spring 完成后调用函数

    我正在使用动画以便弹出窗口从右侧进入 我为此使用以下代码 var toValue 200 if this state fileMenu toValue 0 Animated spring this state bounceValue toV
  • Cgo 找不到像 这样的标准库

    我试图在我的 Go 代码中包含 C 代码 但未被识别 我首先认为它认为它是 C 代码并尝试 并失败 编译 但删除包含行实际上给了我这样的 C 错误故障排除error cout is not a member of std 该代码可以使用 g
  • 为什么从 .dll 导入函数时需要 .lib 文件?

    你能帮我理解 为什么从 dll 导入函数和数据时需要 lib 文件吗 我听说它包含来自相应 dll 的导出函数和数据元素的列表 但是当我使用 CFF Explorer 探索我的 dll 时 我发现 dll 已经具有导出函数的地址 因此理论上
  • 导致运行时异常在控制台输出中使用 println 正确排序

    VM Java 控制台输出的一个常见问题是 System out 和 System err 通常未正确同步 可能是因为它们位于不同的线程上 这会导致混合输出 如下所示 调试输出与运行时异常堆栈跟踪混合在一起 8 1 3 5 9 13 15
  • IBOutlets 在 Xamarin.iOS 中为私有的原因是什么

    生成的 Designer cs 属性默认是私有的 至少不需要手动调整生成的代码 这使得针对 UITableViewCell 等内容进行编码与在 Objective C 中进行编码相比有很大不同 对于 UIxxxViewCells 来说 流行
  • 无法解析:org.jitsi.react:jitsi-meet-sdk:+

    我正在尝试将 Jitsi Meet Android SDK 集成到本机 Android 中的一个简单项目中 但无法构建并引发以下错误 Failed to resolve org jitsi react jitsi meet sdk 我跟着j
  • pthread_join 损坏堆栈中的 pthread_create 参数

    我从一本高级 Linux 编程书中得到了这段代码 当我尝试在Linux 64位环境下执行代码时 which prime之后变量被损坏 更改为 0 pthread join 函数调用 在这个例子中为什么值which prime运行 pthre