我试图掌握POSIX线程的使用并创建了一个简单的程序,它简单地将全局变量递增10个。有时它会一直运行得很好,另外它会在随机点中出现错误。虽然这种类型的问题似乎是线程的常见问题,但我无法理解为什么会在这样一个简单的例子中发生这种情况。我当前的想法可能是由于没有加入线程,父级正在结束,但如果我尝试在第一个线程上加入i seg fault ... Join语句留在但注释掉了。加入是否使用正确的语法?是不是预先形成了导致seg错误的连接?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#define NUMPHILO 5
thread_t threads[NUMPHILO]; //array of threads
pthread_mutex_t mutex; // initialize mutex
int x = 5; //for test
int y = 10;
int philofunct(){
pthread_mutex_lock (&mutex);
x = x+y;
pthread_mutex_unlock (&mutex);
printf("Philo fucntion x = %d\n",x);
return x;
}
int main(){
pthread_mutex_init(&mutex, NULL);
for(int i = 0; i < NUMPHILO; i++){
printf("creating thread[%i]\n",i);
if( pthread_create(&threads[i], NULL, (void *)philofunct(),(void *) &i) != 0)
fprintf(stderr, "%s", strerror(errno));
// pthread_join(threads[i],NULL);
// printf("Threads Joined\n");
}
pthread_mutex_destroy(&mutex);
printf("Threads created\n");
}
输出:
creating thread[0]
Philo fucntion x = 15
creating thread[1]
Philo fucntion x = 25
creating thread[2]
Philo fucntion x = 35
creating thread[3]
Philo fucntion x = 45
creating thread[4]
Philo fucntion x = 55
Threads created
下次跑了:
creating thread[0]
Philo fucntion x = 15
creating thread[1]
Philo fucntion x = 25
creating thread[2]
Philo fucntion x = 35
Segmentation fault (core dumped)
与往常一样,非常感谢任何帮助。
答案 0 :(得分:4)
在考虑您的需求之前,我发现您的代码存在一些问题:
x
。pthread_join
全部。或者,您可以pthread_exit
主线程而不是让main
终止(并且永远不会破坏互斥,这不是泄漏,因为那里只有其中一个,其生命周期以生命周期结束该程序),但杀死主线程有时会使有趣的内核&#34;错误&#34;发生。答案 1 :(得分:4)
你遇到的主要问题是:
if( pthread_create(&threads[i], NULL, (void *)philofunct(),(void *) &i) != 0)
仔细看,您正在调用philofunct()
而不是将函数指针传递给它。更糟糕的是,您将philofunct()
的返回值作为15
的函数指针传递,这是pthread_create()
之类的整数。当然,当线程尝试从15
等地址执行代码时,线程将会被segv。
正确定义philofunct()
之后:
void *philofunct(void *arg)
然后,您可以在没有演员阵容的情况下致电pthread_create()
:
if( pthread_create(&threads[i], NULL, philofunct,(void *) &i) != 0)
另外,如果你想加入你的线程,你应该在它们全部运行后加入你的线程。如果在创建循环中加入线程,则在创建下一个线程之前,您将等待每个线程完成。所以你会这样写:
for (i=0;i<NUMPHILO; i++) {
pthread_create(&threads[i], ...);
// Other stuff...
}
for (i=0;i<NUMPHILO; i++)
pthread_join(threads[i], NULL);
答案 2 :(得分:1)
主线程在子线程完成之前销毁互斥锁。 pthread_join
将解决问题,但pthread_join
需要在创建所有线程后的单独循环中。
for(int i = 0; i < NUMPHILO; i++)
pthread_join(threads[i],NULL);
philofunct
的功能签名是错误的。一般来说,如果你需要演员,你做错了。 (是的,在某些情况下,演员阵容是必要且有用的。这不是其中之一。)正确的签名是
void *philofunct( void *arg );
正确调用pthread_create
if( pthread_create(&threads[i], NULL, philofunct, NULL) != 0)
请注意,传递i
的地址不会达到您想要的效果,但这是一个单独的问题,而您还没有达到这一点。