我正在用pthreads做一个项目,我不能再进一步了。我有3个线程,一个线程应通过I2C(SMBUS)读取一些传感器值,一个应使用第一个线程提供的数据计算一些东西,最后一个线程将在屏幕上打印数据。互斥体应负责线程之间的同步。如何在线程中使用无限while
循环,因为我的线程不只是“完成工作并完成”?它们将永远持续(或者直到按下Ctrl + C键)。
我应该在哪里放置pthread_join
函数?
我的第一种方法如下,但它无法正常工作:
感谢您的帮助。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
typedef struct vector {
double x;
double y;
double z;
} vector_t;
typedef struct all_vectors {
vector_t *gyro;
vector_t *accel;
vector_t *magnet;
} vectors_t;
vectors_t *vectors;
pthread_t th1, th2, th3;
pthread_mutex_t mutex;
int main()
{
initSensors(); //defined in another .c file
pthread_mutex_init(&mutex, NULL);
pthread_create(&th1, NULL, (void *) &readSensors, (void *) vectors);
pthread_create(&th2, NULL, (void *) &calculateAngle, NULL);
pthread_create(&th3, NULL, (void *) &printData, NULL);
while(1)
{
sleep(1);
}
/* The program never reaches the following codes ? */
pthread_mutex_destroy(&mutex);
pthread_exit(NULL);
}
void readSensors(void *vectors)
{
vectors_t *vecs = (vectors_t *)vectors;
while(1)
{
pthread_mutex_trylock(&mutex);
readGyro(vecs->gyro); //defined in another .c file
readAccel(vecs->accel); //defined in another .c file
readMagnet(vecs->magnet); //defined in another .c file
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void calculateAngle()
{
while(1)
{
pthread_mutex_trylock(&mutex);
doSomeCalculation(vectors); //defined in another .c file
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void printData()
{
while(1)
{
pthread_mutex_trylock(&mutex);
printf("%lf, %lf, %lf, lf, %lf, %lf, lf, %lf, %lf", \
vectors->accel->x, vectors->accel->y, vectors->accel->z, \
vectors->gyro->x, vectors->gyro->y, vectors->gyro->z, \
vectors->magnet->x, vectors->magnet->y, vectors->magnet->z );
pthread_mutex_unlock(&mutex);
fflush(stdout);
}
pthread_exit(NULL);
}
答案 0 :(得分:2)
你似乎对这个无限循环之后的代码感到惊讶
while(1)
{
sleep(1);
}
未执行。即使代码可以达到这一行
pthread_mutex_destroy(&mutex);
你会遇到问题,因为线程仍在使用互斥锁。如果你想要正常关闭你的代码,我会添加一个你在线程中循环的全局布尔值,然后添加一个SIGINT处理程序将其设置为false,以便线程可以退出。然后在main中,删除无限while循环并在每个线程上调用pthread_join
,最后销毁互斥锁并最终退出main()
。
pthread_join
调用将阻塞,直到线程退出,因此不需要main()
循环。线程将在SIGINT上正常退出,程序应该运行并以干净的方式终止。
最后一个观察结果:因为vectors
是一个全局变量,所以你不需要通过void*
参数将它传递给线程,因为它已经可见了。
答案 1 :(得分:0)
你可能有无限循环,但是你已经检测到这意味着退出程序的唯一方法是通过中断,这将不允许程序正确清理。
如果你想要清理它(包括加入线程等),那么你需要提供一种循环可以退出的方法。一种方法可以是共享变量,它将响应某些事件而设置,并且处于每个循环的条件中,以便一旦设置,所有线程都将退出。
您可以为SIGINT设置信号处理程序以捕获ctrl-c并设置共享变量。
您从main()调用pthread_join以等待线程退出。你不需要在main中使用循环,它会等到你加入的线程完成。