2

我正在尝试学习如何使用 POSIX 线程在 C 中编写并行算法。我的环境是带有 gcc 4 的 Mac OS X 10.5.5。

编译:

gcc -Wall -D_REENTRANT -lpthread source.c -o test.o

所以,我的问题是,如果我在 Ubuntu 9.04 机器中编译它,它会以线程顺序顺利运行,在 Mac 上看起来互斥锁不起作用,线程不会等待获取共享信息。

苹果电脑:

#1
#0
#2
#5
#3
#4

ubuntu

#0
#1
#2
#3
#4
#5

有任何想法吗?

按照下面的源代码:

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

#define NUM_THREADS 6
pthread_mutex_t mutexsum;
pthread_t threads[NUM_THREADS];
long Sum;

void *SumThreads(void *threadid){
    int tmp;
    int i,x[10],y[10];

    // Para cada x e y do vetor, jogamos o valor de i, só para meio didáticos
    for (i=0; i<10 ; i++){
        x[i] = i;
        y[i] = i;
    }


    tmp = Sum;
     for (i=0; i<10 ; i++){
         tmp += (x[i] * y[i]);
     }

       pthread_mutex_lock (&mutexsum);
       Sum += tmp;
       printf("Im thread #%ld sum until now is: %ld\n",threadid,Sum);
       pthread_mutex_unlock (&mutexsum);
       return 0;
}


int main(int argc, char *argv[]){
    int i;
    Sum = 0;

    pthread_mutex_init(&mutexsum, NULL);

    for(i=0; i<NUM_THREADS; i++){
        pthread_create(&threads[i], NULL, SumThreads, (void *)i);
    }

    pthread_exit(NULL);
}
4

3 回答 3

10

您的代码中没有任何内容可以使您的线程以任何顺序运行。如果在 Ubuntu 中以某种顺序运行,那可能是因为你很幸运。尝试在 Ubuntu 中运行 1000 次,看看是否一遍又一遍地得到相同的结果。

问题是,您无法控制调度程序使您的线程访问处理器的方式。因此,当您遍历for循环以创建线程时,您不能假设对pthread_create的第一次调用将首先运行,或者将首先锁定您正在创建的互斥锁。这取决于它在操作系统级别的调度程序,您无法控制它,除非您编写自己的内核:-)。

如果您想要串行行为,为什么首先要在单独的线程中运行代码?如果只是为了实验,那么我可以考虑使用 pthread_signal 唤醒特定线程并使其运行的一种解决方案......然后被唤醒的线程可以唤醒第二个线程,依此类推。

希望能帮助到你。

于 2009-09-11T12:52:39.443 回答
0

我记得,您保护的变量实际上并没有在进程之间共享。它存在于每个线程内的自己的上下文中。因此,实际上只是每个线程何时被安排来确定将打印的内容。

如果正确性被定义为打印 0、1、2、3 ...,我认为一个简单的互斥体不会让您保证正确性

您的代码正在做的是创建多个执行上下文,使用 sum 函数中的代码作为其执行代码。除非声明为静态变量,否则您要保护的变量对于该函数的每次调用都是唯一的。

最后,您让一个系统正确打印出来是巧合,因为您没有逻辑方法来阻塞线程,直到轮到它们正确为止。

于 2009-09-11T12:50:32.270 回答
0

我不使用 C 或任何其他语言进行 pthreads(但我在高性能计算机上进行线程编程),所以这个“答案”可能对你没用;

  • 您的代码中的什么要求线程按线程 ID 顺序传递互斥锁?我看到线程是按 id 顺序创建的,但是需要它们按该顺序执行 /

  • 如果您确实需要您的线程以 id 顺序执行,为什么?好像您正在创建线程,然后将它们序列化。达到什么目的?

  • 当我在线程中编程并担心执行顺序时,我经常尝试创建大量线程并查看执行顺序会发生什么。

正如我所说,如果我对 C 和 pthreads 的理解太差,请忽略这一点。

于 2009-09-11T12:51:22.003 回答