pthreads在线程之间共享内存

时间:2014-03-14 11:30:47

标签: c linux multithreading pthreads

所以我有一小段代码,理论上可以很容易地进行组合。

结构非常简单,与以下内容非常相似:

for (int i = 0; i < some_value; ++i) {
    // we have a function called do_stuff
    // somewhere in the code

    // Create a new pthread
    // using do_stuff as start routine
}

现在所有变量都不在线程之间共享。也就是说,线程之间不需要相互之间的通信。但是我确实使用变量i将数据写入数组等。

我想知道的是:如果我将变量i作为pthread启动例程的参数传递,并且i的值发生了变化(因为i在下一个时会增加循环迭代),现有线程中i的值是否也会改变?

2 个答案:

答案 0 :(得分:5)

如果您将i的地址传递给所有函数,并且每个函数都尝试修改它,那么当然i搞乱了,因为它们都具有相同变量的地址。你需要的是给每个线程提供他们需要处理的范围,让他们用局部变量迭代它。像这样:

struct thread_data
{
    int start;
    int end;
    pthread_t tid;
};

struct thread_data td[N]; // assuming N threads

/* divide up the ranges */
for (i = 0; i < N; ++i)
    td[i] = (struct thread_data){ .start = i*len/N, .end = (i+1)*len/N };
td[N-1].end = len;

/* create the threads */
for (i = 0; i < N; ++i)
    pthread_create(&td[i].tid, NULL, func, &td[i]);

和func:

void *func(void *arg)
{
    struct thread_data *data = arg;

    for (int i = data->start; i < data->end; ++i)
        /* do some work */
}

您可能也有兴趣了解OpenMP,它旨在自动完全满足您的要求。

答案 1 :(得分:1)

如果您提供指向多个线程的指针,则它们的行为可能会修改以不确定方式指向的值。如果在线程之间共享变量,则应使用信号量或互斥量来管理线程之间的读/写访问。

如果您知道线程只访问不同的内存位置,则不需要这样做。例如,如果每个线程在同一个数组中写入但是对于不同的索引,则不需要保护数组。

修改

如果提供变量i的地址,那么它将在循环外部修改。但是,如果在循环中创建一个临时变量并传递其地址,那么你会没事的。这个例子可以帮助您了解发生了什么: http://timmurphy.org/2010/05/04/pthreads-in-c-a-minimal-working-example/

在C中,无论何时提供指向函数的指针,它指向的值都可以从该函数的内部和外部修改(无论它是否在同一个线程上)。 pthread_create要求您以void *的形式提供起始例程的参数,因此任何具有指向同一变量的指针的内容都可以随时修改其值。

正如@Shahbaz建议的那样,您可能对OpenMP感兴趣。使用OpenMP,您可以在代码中添加编译指示以便于创建线程。您还可以指定线程是否共享变量。