我正在尝试为需要类似以下内容的问题实施多线程解决方案
如何在每次创建线程时更改“k”以使其从0开始,并以“n - 1”结束,以便每个线程只访问其指定的数组元素?
答案 0 :(得分:1)
这适用于(在POSIX平台上...)并且是他的答案中提到的@Some Programmer Dude方法的实现。它应该是可移植且符合标准的,只要实现提供intptr_t
作为类型(它是可选的):
void *start_func( void *arg )
{
int myID = ( intptr_t ) arg;
.
.
.
return( NULL );
}
int main( int argc, char **argv )
{
.
.
.
pthread_t tid[ n ];
for ( int k = 0; k < n; i++ )
{
pthread_create( &tid[ k ], NULL, start_func, ( void * )( intptr_t ) k );
}
.
.
.
return( 0 );
}
您需要注意sizeof( int )
大于sizeof( intptr_t )
且的任何架构,您的循环值会溢出intptr_t
,但是据我所知,这样的架构根本不存在。
答案 1 :(得分:1)
让我强调一下,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* 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);
}
这更像是将回传上下文数据传递给回调函数的常规方式。您可以将所需的所有内容放在Context结构中的线程中,而不是依赖于全局变量。
答案 2 :(得分:0)
虽然有点气馁,但可以将k
的值传递给线程函数,并进行一些来回转换。
或者您可以动态分配unsigned int
(每个线程一个)来存储k
的值,并将该指针传递给线程函数(复制它然后释放分配的内存)。这是安全和便携的。
答案 3 :(得分:0)
正确的方法是:
这种方法是可重入的,因为每个线程都有自己的变量。