是否有可能在pthread中有一个无限循环?

时间:2014-01-10 00:07:54

标签: c linux pthreads infinite-loop

我正在用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);
}

2 个答案:

答案 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中使用循环,它会等到你加入的线程完成。