C 具有每个线程唯一变量的多线程处理

C 具有每个线程唯一变量的多线程处理,c,arrays,multithreading,scope,C,Arrays,Multithreading,Scope,我正在尝试实现一个多线程解决方案来解决一个需要如下内容的问题 我创建“n”个线程 我有一个大小为“n-1”的数组 每个线程应该只访问其相应的数组元素(即线程0应该只影响数组的元素0,线程1应该只影响数组的元素1,依此类推) 每个线程将执行通过索引“k”引用数组的相同函数 如何在每次创建线程时更改“k”,使其从0开始,在“n-1”结束,这样每个线程将只访问其分配的数组元素?虽然有点不鼓励这样做,但您可以通过一些来回转换将k的值传递给线程函数 或者,您可以动态分配一个无符号int(每个线程一个)

我正在尝试实现一个多线程解决方案来解决一个需要如下内容的问题

  • 我创建“n”个线程
  • 我有一个大小为“n-1”的数组
  • 每个线程应该只访问其相应的数组元素(即线程0应该只影响数组的元素0,线程1应该只影响数组的元素1,依此类推)
  • 每个线程将执行通过索引“k”引用数组的相同函数

如何在每次创建线程时更改“k”,使其从0开始,在“n-1”结束,这样每个线程将只访问其分配的数组元素?

虽然有点不鼓励这样做,但您可以通过一些来回转换将
k
的值传递给线程函数


或者,您可以动态分配一个
无符号int
(每个线程一个),以存储
k
的值,并将该指针传递给线程函数(该函数复制它,然后释放分配的内存)。这是安全且可移植的。

虽然有点不鼓励这样做,但您可以通过一些来回转换将
k
的值传递给线程函数


或者,您可以动态分配一个
无符号int
(每个线程一个),以存储
k
的值,并将该指针传递给线程函数(该函数复制它,然后释放分配的内存)。这样做既安全又便于携带。

正确的方法是:

  • 在创建线程的调用程序中分配变量
  • 创建时,将指向变量的指针作为参数传递给线程
  • 在线程回调中,将指针转换回正确的指针类型
  • 取消引用指针并读取内容

这种方法是可重入的,因为每个线程都有自己的变量。

正确的方法是:

  • 在创建线程的调用程序中分配变量
  • 创建时,将指向变量的指针作为参数传递给线程
  • 在线程回调中,将指针转换回正确的指针类型
  • 取消引用指针并读取内容
这种方法是可重入的,因为每个线程都有自己的变量。

这种方法有效(在POSIX平台上…),并且是某个程序员在回答中提到的方法的实现。只要实现将
intptr\u t
作为一种类型提供(可选),它就应该是可移植的、符合标准的:

void*start\u func(void*arg)
{
int myID=(intptr_t)arg;
.
.
.
返回(空);
}
int main(int argc,字符**argv)
{
.
.
.
pthread_t tid[n];
对于(int k=0;k
对于
sizeof(int)
大于
sizeof(intptr\u t)
且循环值会溢出
intptr\u t
的任何体系结构,您都需要小心,但据我所知,这样的体系结构根本不存在。

这是可行的(在POSIX平台上…)这是一个方法的实现@someprogrammerdude在他的回答中提到。只要实现将
intptr\u t
作为一种类型提供(可选),它就应该是可移植的、符合标准的:

void*start\u func(void*arg)
{
int myID=(intptr_t)arg;
.
.
.
返回(空);
}
int main(int argc,字符**argv)
{
.
.
.
pthread_t tid[n];
对于(int k=0;k

对于
sizeof(int)
大于
sizeof(intptr\t)
且循环值会溢出
intptr\t
的任何体系结构,您都需要小心,但据我所知,这样的体系结构根本不存在。

让我强调,Andrew Henle接受的答案非常好,可以在我使用过的每一个C环境中工作,尽管他说它是可移植的和符合标准的在技术上是不正确的

我想我更喜欢以下两种解决方案中的任何一种

  • 将直接指针传递给元素

    typedef /* whatever */ } MyType;
    MyType* array;
    int main(int argc, char*argv[])
    {
        // find out what n is
        array = calloc(n, sizeof *array);
        // some stuff including filling in array
        pthread_t tid[n];
        for (int k = 0; k < n; k++)
        {
            pthread_create( &tid[k], NULL, startFunc, &array[k]);
        }
        // do stuff including wait for the threads to finish
    }
    
    void startFunc(void* param)
    {
        MyType* myObject = (MyType*)param;
        // Do stuff directly on myObject
        // or if you *really* need to recover k:
        ptrdiff_t k = myObject - array;
    }
    
    typedef/*whatever*/}MyType;
    MyType*数组;
    int main(int argc,char*argv[])
    {
    //找出n是什么
    array=calloc(n,sizeof*array);
    //一些东西,包括填充数组
    pthread_t tid[n];
    对于(int k=0;k
    我喜欢这个解决方案,因为线程不需要知道它正在处理的单个数据段的上下文

  • 创建一个上下文类型以传递给threadstart函数,并将所需的所有内容放入其中

    typedef /* whatever */ } MyType;
    MyType* array;
    struct ThreadContext
    {
        pthread_t tid;
        int k;
        MyType *array;
        size_t arraySize;
    }
    
    int main(int argc, char*argv[])
    {
        // find out what n is
        array = calloc(n, sizeof *array);
        // some stuff including filling in the array
        struct Context* contexts = calloc(n, sizeof *contexts);
        for (int k = 0; k < n; k++)
        {
            contexts[k].array = array;
            contexts[k].arraySize = n;
            contexts[k].k = k;
            pthread_create( &(contexts[k].tid), NULL, startFunc, &contexts[k]);
        }
        // do stuff including wait for the threads to finish
    }
    
    void startFunc(void* param)
    {
        struct Context* context= (struct Context*)param;
        doSomethingWithArrayObject(context->array, context->k);
    }
    
    typedef/*whatever*/}MyType;
    MyType*数组;
    结构线程上下文
    {
    pthread_t tid;
    int k;
    MyType*数组;
    大小排列;
    }
    int main(int argc,char*argv[])
    {
    //找出n是什么
    array=calloc(n,sizeof*array);
    //一些东西,包括填充数组
    struct Context*contexts=calloc(n,sizeof*contexts);
    对于(int k=0;ktypedef /* whatever */ } MyType;
    MyType* array;
    struct ThreadContext
    {
        pthread_t tid;
        int k;
        MyType *array;
        size_t arraySize;
    }
    
    int main(int argc, char*argv[])
    {
        // find out what n is
        array = calloc(n, sizeof *array);
        // some stuff including filling in the array
        struct Context* contexts = calloc(n, sizeof *contexts);
        for (int k = 0; k < n; k++)
        {
            contexts[k].array = array;
            contexts[k].arraySize = n;
            contexts[k].k = k;
            pthread_create( &(contexts[k].tid), NULL, startFunc, &contexts[k]);
        }
        // do stuff including wait for the threads to finish
    }
    
    void startFunc(void* param)
    {
        struct Context* context= (struct Context*)param;
        doSomethingWithArrayObject(context->array, context->k);
    }