POSIX C线程 - 将整数传递给线程函数

时间:2014-04-13 19:26:39

标签: c multithreading pointers posix void-pointers

我的程序中存在分段错误错误。我在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行:警告:从不同大小的整数转换为指针)

编译错误已经解决,但现在当我运行程序时,它显示了这个:分段错误:11(核心转储)

可能之前的警告尚未解决,但我不知道如何修复它......

3 个答案:

答案 0 :(得分:1)

您需要为变量i分配内存。现在它是一个指向某处的指针,但你绝对不会欠那段记忆。

之后

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

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

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

答案 1 :(得分:1)

我做了一些改变:

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

  4. #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 
    

答案 2 :(得分:1)

如果要做的只是将 id 传递给调用线程,可以将隐藏在 void*参数中,然后执行此操作可移植。使用像intptr_t这样的整数类型,这是你的平台上“足够容纳数据指针的整数”,我很确定这更接近你想要的。

此外,POSIX要求FILE*上的stdio函数是线程安全的,所以你可能会丢失fflush()(这无论如何都没有帮助),不过如果你要搜索为什么会这样,这是不明显的。查看flockfile()的文档,并注意提及所有在FILE*上运行的stdio函数(其中printf()stdout执行的操作)的行为应该像调用{{ {1}}和flockfile获取对流的访问权。)没有关于锁定的原子性的规范(对于你所知道的所有内容,它可以归结为字符,其中案例交错运行,但它应该仍然是安全的。

funlockfile

<强>输出

#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 进行双重拍摄,那么您应该值得花时间阅读this question and answers。它是使用正确的“%”类型将PRIiPTR转储为格式化数据的便携式机制。