macos Mac OS X 中的 Pthreads - 互斥体问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1410633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pthreads in Mac OS X - Mutexes issue
提问by rafaelxy
I'm trying to learn how to program parallel algorithms in C using POSIX threads. My environment is a Mac OS X 10.5.5 with gcc 4.
我正在尝试学习如何使用 POSIX 线程在 C 中编写并行算法。我的环境是带有 gcc 4 的 Mac OS X 10.5.5。
Compiling:
编译:
gcc -Wall -D_REENTRANT -lpthread source.c -o test.o
So, my problem is, if I compile this in a Ubuntu 9.04 box, it runs smoothly in thread order, on Mac looks like mutexes doesn't work and the threads don't wait to get the shared information.
所以,我的问题是,如果我在 Ubuntu 9.04 盒子中编译它,它会按线程顺序顺利运行,在 Mac 上看起来互斥锁不起作用,线程不等待获取共享信息。
Mac:
苹果电脑:
#1
#0
#2
#5
#3
#4
ubuntu
乌本图
#0
#1
#2
#3
#4
#5
Any ideas?
有任何想法吗?
Follow below the source code:
按照下面的源代码:
#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);
}
回答by Pablo Santa Cruz
There is nothing on your code that will make your threads running in ANYorder. If in Ubuntu is running on some order, it might be because you are just lucky. Try running 1000 times in Ubuntu and see if you get the same results over and over again.
您的代码中没有任何内容可以使您的线程以任何顺序运行。如果在 Ubuntu 中以某种顺序运行,那可能是因为你很幸运。尝试在 Ubuntu 中运行 1000 次,看看是否一遍又一遍地得到相同的结果。
The thing is, that you can't control the way the scheduler will make your threads access the processor(s). So, when you iterate through the forloop is creating your threads, you can't assume that the first call to pthread_createwill get to run first, or will get to lock the mutex you are creating first. It's up to the scheduler which it at the OS level, and you can't control it, unless you write your own kernel :-).
问题是,您无法控制调度程序使您的线程访问处理器的方式。因此,当您遍历for循环以创建线程时,您不能假设对pthread_create的第一次调用将首先运行,或者将首先锁定您正在创建的互斥锁。这取决于操作系统级别的调度程序,您无法控制它,除非您编写自己的内核:-)。
If you want a serial behavior why would you run your code in separate threads in the first place? If it is just for experimentation, then one solution I can think of using pthread_signal to wake a specific thread up and make it running... Then the woken up thread can wake up the second one and so on so forth.
如果您想要串行行为,为什么首先要在单独的线程中运行代码?如果只是为了实验,那么我可以想到使用 pthread_signal 唤醒特定线程并使其运行的一种解决方案......然后被唤醒的线程可以唤醒第二个线程,依此类推。
Hope it helps.
希望能帮助到你。
回答by San Jacinto
To my recollection, the variable you have protected isn't actually being shared amongst the processes. It exists in its own context inside each of the threads. So, it's really just a matter of when each thread gets scheduled that determines what will print.
据我所知,您保护的变量实际上并未在进程之间共享。它存在于每个线程内的自己的上下文中。因此,这实际上只是每个线程被调度的时间决定将打印什么的问题。
I don't think one simple mutex will allow you to guarantee correctness, if correctness is defined as printing 0, 1, 2, 3 ...
如果正确性被定义为打印 0, 1, 2, 3 ...
what your code is doing is creating multiple execution contexts, using the code in your sum function as its execution code. the variable you are protecting, unless declared as static, will be unique to each call of that function.
您的代码正在做的是创建多个执行上下文,使用 sum 函数中的代码作为其执行代码。您正在保护的变量,除非声明为静态,否则对该函数的每次调用都是唯一的。
in the end, it is coincidence that you are getting one system to print out correctly, because you have no logical method of blocking threads until it is their proper turn.
最后,您让一个系统正确打印出来是巧合,因为您没有逻辑方法来阻塞线程,直到它们正确轮到它们为止。
回答by High Performance Mark
I don't do pthreads in C or any other language (but I do thread programming on high-performace computers) so this 'answer' might be useless to you;
我不使用 C 或任何其他语言进行 pthreads(但我在高性能计算机上进行线程编程),因此这个“答案”可能对您无用;
What in your code requires the threads to pass the mutex in thread id order ? I see that the threads are created in id order, but what requires them to execute in that order /
If you do require your threads to execute in id order, why ? It seems a bit as if you are creating threads, then serialising them. To what end ?
When I program in threads and worry about execution order, I often try creating a very large number of threads and seeing what happens to the execution order.
您的代码中什么要求线程以线程 ID 顺序传递互斥锁?我看到线程是按 id 顺序创建的,但是需要它们按该顺序执行 /
如果您确实要求您的线程按 id 顺序执行,为什么?看起来有点像您正在创建线程,然后将它们序列化。什么目的?
当我在线程中编程并担心执行顺序时,我经常尝试创建大量线程并查看执行顺序会发生什么。
As I say, ignore this if my lack of understanding of C and pthreads is too poor.
正如我所说,如果我对 C 和 pthreads 缺乏了解太差,请忽略这一点。