2014-01-10 38 views
0

我正在用pthreads做一个项目,我不能走得更远。我有3个线程,一个线程应该通过I2C(SMBUS)读取一些传感器值,一个应该使用第一个线程占用的数据计算一些东西,最后一个线程应该在屏幕上打印数据。互斥体应负责线程之间的同步。我如何在线程中使用无限循环,因为我的线程不只是“完成任务并完成”?他们应该永远持续下去(或者直到按下Ctrl + C键)。pthread中可能有无限循环吗?

我应该在哪里放置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); 
} 
+1

你有4个无限循环 - 什么不工作?如果你打算让你的线程永久运行,那么加入它们就没有意义了 - 将它们创建为分离的。你真的似乎缺少的是沟通和协调线程努力的一种方式。 – Duck

+0

如果我不使用线程,数据显示正确,但如果我使用线程数据显示不正确。 –

+0

我知道。你现在有4个独立的演员。你必须协调他们。有1个线程读取,1个线程计算和1个线程打印是一回事。让他们以正确的顺序完成所有工作以产生预期产出是另一回事。你需要查看队列,条件变量等内容,如果你想这个工作。 – Duck

回答

2

你似乎感到惊讶的是这个代码无限循环不执行

while(1) 
{ 
    sleep(1); 
} 

后。即使代码可以达到这一行

pthread_mutex_destroy(&mutex); 

你会有问题,因为线程仍在使用互斥锁。如果你想要正常关闭你的代码,我会在你的线程中添加一个全局布尔值,然后添加一个SIGINT处理器来将它设置为false,以便线程可以退出。然后在main中,删除那个无限while循环并在每个线程上调用pthread_join,最后销毁互斥锁​​并最终退出main()

pthread_join调用将阻塞,直到线程退出,因此您的main()循环不需要。线程将在SIGINT上优雅地退出,程序应该以干净的方式运行和终止。

最后一个观察:由于vectors是一个全局变量,因此您不需要通过void*参数将它传递给线程,因为它已经可见。

+0

嗯,好主意。谢谢。我会尝试。 –

0

你可能会有无限循环,但正如你已经发现,这意味着退出程序的唯一方法是通过中断,这将不允许程序正常清理。

如果你想清理它(包括连接线程等),那么你需要提供一个循环可以退出的方式。一种方法可能是一个共享变量,它将响应某个事件而设置,并处于每个循环的条件中,以便一旦设置完所有线程都将退出。

您可以设置SIGINT的信号处理程序来捕获ctrl-c并设置共享变量。

您可以从main()中调用pthread_join等待线程退出。你不需要主循环,它会等待直到你加入的线程完成。