【问题标题】:POSIX C Threads - Passing integer to thread funcPOSIX C 线程 - 将整数传递给线程函数
【发布时间】:2014-04-13 19:26:38
【问题描述】:

我的程序中有分段错误错误。我正在使用 POSIX C 中的多线程程序进行练习。我在 FREEBSD 系统中运行这些程序。

这是我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#define NUM_THREADS 15

void *PrintHello(void *threadid)
{
        printf("Hello World from thread: %p \n", threadid);
        fflush(NULL);
        pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
        int rtrn, *i;
        pthread_t threads[NUM_THREADS];

        for((*i)=0; (*i)<NUM_THREADS; (*i)++)
        {
                if( pthread_create(&threads[(*i)], NULL, PrintHello, (void *)i) != 0)
                {
                        printf("Error code %d detected while thread %d was being created.", rtrn, *i);
                }
        }
        return 0;
}

我不得不将 i 整数变量转换为指针整数,因为这解决了编译期间的错误(第 22 行:警告:从不同大小的整数转换为指针)

编译错误已解决,但现在当我运行程序时,它显示:Segmentation fault: 11 (core dumped)

可能之前的警告还没有解决,但我不知道如何解决它......

【问题讨论】:

  • 你永远不会将i 初始化为合理的值。

标签: c multithreading pointers posix void-pointers


【解决方案1】:

如果您只想将 id 传递给调用线程,您可以通过将其埋在 in void* 参数中来实现,并且可移植地这样做。使用像intptr_t 这样的整数类型,它是在您的平台上“大到足以容纳数据指针的整数”,我很确定这更接近您想要的。

此外,POSIX 要求 FILE* 上的 stdio 函数是线程安全的,因此您可能会丢失 fflush() (无论如何这并没有真正的帮助),但如果您要搜索这是为什么,这并不明显。查看flockfile() 的文档,并注意提及所有在FILE* 上运行的stdio 函数(其中printf()stdout 上运行)应该表现得好像它们调用flockfilefunlockfile 来获取访问流。)没有关于锁定的原子性的规范(它可能取决于你所知道的字符,在这种情况下交错运行异常)但它仍然应该是无 -不太安全。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <inttypes.h>

#define NUM_THREADS 15

void *PrintHello(void *threadid)
{
    intptr_t id = (intptr_t)threadid;
    printf("Hello World from thread: %" PRIiPTR "\n", id);
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_t threads[NUM_THREADS];
    intptr_t i=0;
    int res;

    for(i=0; i<NUM_THREADS; ++i)
    {
        if( (res = pthread_create(threads+i, NULL, PrintHello, (void *)i)) != 0)
            printf("Error code %d detected while thread %" PRIiPTR " was being created.", res, i);
    }

    // wait for all to complete
    for (i=0;i<NUM_THREADS;++i)
        pthread_join(threads[i], NULL);

    return 0;
}

输出

Hello World from thread: 0
Hello World from thread: 1
Hello World from thread: 2
Hello World from thread: 3
Hello World from thread: 4
Hello World from thread: 5
Hello World from thread: 6
Hello World from thread: 7
Hello World from thread: 8
Hello World from thread: 9
Hello World from thread: 10
Hello World from thread: 11
Hello World from thread: 12
Hello World from thread: 14
Hello World from thread: 13

最后,如果您对隐藏在格式字符串中的奇怪的PRIiPTR 进行双重了解,那么您应该花时间阅读this question and answers。这是使用正确的“%”类型将intptr_t转储为格式化数据的可移植机制。

【讨论】:

    【解决方案2】:

    您需要为变量i 分配内存。现在它是一个指向某个地方的指针,但你绝对不欠那块内存。

    之后

    i = calloc(1, sizeof(int));
    

    您将拥有一段有效的内存,初始化为 0(感谢calloc)。

    另一方面,如果您将通过指针使用i,您可能会有一个有趣的行为,具体取决于您的操作系统如何启动线程。所有线程都将使用相同的地址,因此其中一些线程可能会在屏幕上打印出相同的值 :) 如果您想通过线程打印出 10 个不同的数字,请使用0x90 的答案 :)

    【讨论】:

      【解决方案3】:

      我做了一些改动:

      1. 删除了不必要的头文件。
      2. 为 id 声明了一个全局数组。共享全局数组或堆比堆栈更好。
      3. 使用数组代替指针。

      #include <stdio.h>
      #include <pthread.h>
      
      #define NUM_THREADS 15
      
      void *PrintHello(void *threadid)
      {
          printf("Hello World from thread: %d \n", *(int *)threadid);
          fflush(NULL);
          pthread_exit(NULL);
      }
      
      static int id[NUM_THREADS];
      
      int main(int argc, char *argv[])
      {
          int rtrn;
          pthread_t threads[NUM_THREADS];
      
          for(int i=0; i<NUM_THREADS; i++) {
               id[i] = i; 
               if (pthread_create(&threads[i], NULL, PrintHello, (void *)&id[i]))
                   printf("Error code %d detected while thread %d was being created.", rtrn, i);
      
          }
          return 0;
      }
      

      将输出:

      Hello World from thread: 0 
      Hello World from thread: 1 
      Hello World from thread: 2 
      Hello World from thread: 3 
      Hello World from thread: 4 
      Hello World from thread: 5 
      Hello World from thread: 6 
      Hello World from thread: 7 
      Hello World from thread: 8 
      Hello World from thread: 9 
      Hello World from thread: 10 
      Hello World from thread: 11 
      Hello World from thread: 12 
      Hello World from thread: 13 
      Hello World from thread: 14 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-05
        • 2017-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多