我有这段代码来测试Mac OS X中的pthread。
#include <stdio.h>
#include <string.h>
#include <pthread.h>
// A thread that just exits
void* mythread(void *arg) {
int tArg;
tArg = *(int*)arg;
printf("Received %d\n", tArg);
return 0;
}
int main (int argc, char *argv[]) {
int err, count = 0;
pthread_t thread;
while (1) {
err = pthread_create(&thread, 0, mythread, &count);
if (err != 0) {
printf("Count: %d Error: %d '%s'\n", count, err, strerror(err));
}
count += 500;
if (count == 5000) break;
}
return 0;
}
这是其中一项结果:
Received 3000
Received 3500
Received 3000
Received 3500
Received 3000
Received 3000
Received 3500
Received 4500
Received 4500
Received -2009390077
结果似乎对我来说很奇怪,因为它不是从0开始,而是多个重复和奇怪的最后一个值。可能有什么问题?
答案 0 :(得分:4)
您在每次迭代时都会覆盖thread
,这会产生意想不到的后果。
您将count
的地址传递给线程(int *),它从3000
开始并不奇怪;当第一个线程实际执行时,int
*count
必须已经增加到该值。
其他线程同时从主进程的堆栈中读取相同的值,因此您可以重复。
可以解释最后的结果,因为线程未正确连接。当最后一个线程读取count
时,变量不再在堆栈上,因为main函数返回或正在返回。
正确的代码应该更像这样:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
// A thread that just exits
void* mythread(void *arg) {
int tArg;
tArg = *(int*)arg;
printf("Received %d\n", tArg);
return 0;
}
int main (int argc, char *argv[]) {
int err, num = 0, count[10];
pthread_t thread[10];
for (num = 0; num < 10; num++) {
/* this is horrible, these could be statically initialized */
if (!num)
count[num] = 500;
else count[num] = count[num-1] + 500;
/* each thread should have it's own pthread_t and int* */
/* do not change the count[num] of another thread */
err = pthread_create(&thread[num], 0, mythread, &count[num]);
if (err != 0) {
printf("Count: %d Error: %d '%s'\n", count[num], err, strerror(err));
}
}
for (num = 0; num < 10; num++) {
pthread_join(thread[num], NULL);
}
return 0;
}
请注意,仍然无法保证执行顺序,您可能会得到如下输出:
Received 1000
Received 2000
Received 2500
Received 1500
Received 500
Received 3000
Received 3500
Received 4000
Received 4500
Received 5000
这很正常。