【问题标题】:Multithreading: simple program Segment fault (core dumped)多线程:简单程序段错误(核心转储)
【发布时间】:2018-08-30 22:12:38
【问题描述】:

我正在尝试创建一个计算从 1 到 1000 的素数的程序。我相信代码在创建或加入 pthread 时遇到了问题。我不断收到核心转储错误。我主要关心的是我加入 pthread 的第二个 for 循环。这是检查线程是否已结束的正确方法吗?

我在终端中使用 gcc --std=c99 -Wall -Werror -pthread primes.c -o primes。

    while (test_val <= FINAL){
        //loop to check if thread is finished
        for(int i = 0; i < THREADS; i++){
            if(tid[i] == 0){
                pthread_create(&tid[i], NULL, testprime, NULL);

            }   
        }
        //wait for thread to end
        for(int i = 0; i < THREADS; i++){
            pthread_join(tid[i], NULL);

这是错误: 分段错误(核心转储)

【问题讨论】:

  • 你为什么要用1覆盖线程ID:tid[l] = 1;???
  • 您还在临界区之外阅读test_val。当isprime 设置为false 时,你应该打破循环。
  • 当数字不是素数时,你也应该打印一些东西。这有助于调试...

标签: c linux multithreading operating-system


【解决方案1】:

您只需要在此处更正您的 for 循环。您不需要在数组中分配值。当您调用 pthread_create 时,它会将线程 ID 存储在线程数组的每个位置。

for(int ti = 0; ti < MAX_THREADS; ti++){
        if(tid[ti] == 0){
            pthread_create(&tid[ti], NULL, testprime, NULL);
            //tid[l] = 1;
        }  

【讨论】:

    【解决方案2】:

    这里:

    for(int l = 0; ti < MAX_THREADS; ti++){
        if(tid[l] == 0){
            pthread_create(&tid[l], NULL, testprime, NULL);
            tid[l] = 1;
        }   
    }
    

    pthread_create 的第一个参数是一个输出线程句柄。在下一行,您将此值设置为 1(可能将其标记为已使用)。

    在那些无效句柄上执行pthread_join 时,您调用未定义的行为

    去掉这个赋值,线程句柄不是0,所以你的代码还是可以工作的。

    【讨论】:

    • 谢谢你摆脱了我的错误!但现在我的代码不打印任何东西。这可能是因为我正在运行它的虚拟机吗?还是代码中的其他内容?
    猜你喜欢
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多