我正在尝试学习如何使用POSIX线程在C中编写并行算法。我的环境是带有gcc 4的Mac OS X 10.5.5。
编译:
gcc -Wall -D_REENTRANT -lpthread source.c -o test.o
所以,我的问题是,如果我在Ubuntu 9.04框中编译它,它按顺序运行顺利,在Mac上看起来像互斥锁不起作用,并且线程不等待获取共享信息。
的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);
}
答案 0 :(得分:10)
您的代码中没有任何内容可以让您的主题以 ANY 顺序运行。如果在Ubuntu上运行某个订单,可能是因为你很幸运。尝试在Ubuntu中运行1000次,看看你是否一遍又一遍地得到相同的结果。
问题是,您无法控制调度程序使线程访问处理器的方式。因此,当您遍历 for 循环创建线程时,您不能假设第一次调用 pthread_create 将首先运行,或者将锁定您首先创建的互斥锁。这取决于操作系统级别的调度程序,除非您编写自己的内核,否则无法控制它: - )。
如果您想要串行行为,为什么首先在单独的线程中运行代码?如果它只是用于实验,那么我可以想到一个解决方案,使用pthread_signal唤醒特定线程并使其运行...然后唤醒线程可以唤醒第二个,依此类推。
希望它有所帮助。
答案 1 :(得分:0)
回想一下,你保护的变量实际上并没有在进程之间共享。它存在于每个线程内部的自己的上下文中。因此,这只是每个线程何时进行调度以确定将要打印的内容的问题。
如果正确性定义为打印0,1,2,3 ......我不认为一个简单的互斥锁可以保证正确性。
您的代码正在做的是创建多个执行上下文,使用sum函数中的代码作为其执行代码。您要保护的变量,除非声明为静态,对于该函数的每次调用都是唯一的。
最后,巧合的是你要让一个系统正确打印出来,因为你没有合理的方法来阻止线程,直到它们正常转向。
答案 2 :(得分:0)
我不用C语言或任何其他语言进行pthreads(但我在高性能计算机上进行线程编程)所以这个'回答'可能对你没用;
代码中有什么要求线程以线程ID顺序传递互斥锁?我看到线程是按id顺序创建的,但是要求它们按顺序/
如果您确实要求您的线程以id顺序执行,为什么?看起来好像你正在创建线程,然后将它们序列化。到底是什么?
当我在线程中编程并担心执行顺序时,我经常尝试创建大量线程并查看执行顺序会发生什么。
正如我所说,如果我对C和pthreads缺乏了解,那就忽略这一点。