我想使用 libgps 与 gpsd 守护进程交互。这就是为什么我实现了一个小测试应用程序,以便从特定卫星中提取值。
HOWTO 页面上的文档告诉我们
棘手的部分是解释你从阻塞读取中得到什么。棘手的原因是您不能保证每次读取都会从守护程序中获取一个完整的 JSON 对象。它可以抓取一个响应对象,或多个响应对象,或一个的一部分,或一个或多个后跟一个片段。
按照文档的建议,PACKET_SET
在执行任何其他操作之前检查掩码位。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <gps.h>
#include <pthread.h>
pthread_t t_thread;
struct t_args {
unsigned int ID;
};
unsigned int status = 0;
int elevation;
int p_nmea(void *targs);
void start_test(void)
{
struct t_args *args = malloc(sizeof *args);
status = 1;
args->ID = 10;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if (pthread_create(&t_thread, &attr, (void *)&p_nmea, args) != 0)
{
perror("create: \n");
}
}
int test_result(int * Svalue)
{
int res;
if(status == 1)
{
void * t_res;
if(pthread_tryjoin_np(t_thread, &t_res) != 0)
{
status = 1;
}
else
{
if((int)t_res == 1)
{
res = 3;
*Svalue = elevation;
elevation = 0;
}
else
{
res = 4;
}
}
}
return res;
}
int p_nmea(void *targs)
{
struct t_args *thread_args = targs;
struct gps_data_t gpsdata;
int ret = -1;
int count = 10;
int i,j;
if(gps_open((char *)"localhost", (char *)DEFAULT_GPSD_PORT, &gpsdata) != 0)
{
(void)fprintf(stderr, "cgps: no gpsd running or network error: %d, %s\n", errno, gps_errstr(errno));
return (-1);
}
else
{
(void)gps_stream(&gpsdata, WATCH_ENABLE, NULL);
do
{
if(!gps_waiting(&gpsdata, 1000000))
{
(void)gps_close(&gpsdata);
}
else
{
if(gps_read(&gpsdata) == -1)
{
return (-1);
}
else
{
if(gpsdata.set & PACKET_SET)
{
for (i = 0; i < MAXCHANNELS; i++)
{
for (j = 0; j < gpsdata->satellites_visible; j++)
{
if(gpsdata->PRN[i] == thread_args.ID)
{
elevation = (int)gpsdata->elevation[i];
ret = 1;
break;
}
}
if(gpsdata->PRN[i] == thread_args.ID)
{
break;
}
}
}
}
}
--count;
}while(count != 0);
}
(void)gps_stream(&gpsdata, WATCH_DISABLE, NULL);
(void)gps_close(&gpsdata);
(void)free(thread_args);
(void)pthread_exit((void*) ret);
}
正如文档中所建议的那样,我查看了 cgps 和 gpxlogger 作为示例代码,但 libgps 的微妙之处让我无法理解。之前添加了一个 while 循环gps_waiting()
,以便至少获取一个完整的响应对象。在介绍 pthread 之前,我注意到在返回答案之前需要几秒钟test_result()
后调用该函数。start_test()
通过使用我认为3
会立即返回的线程,然后3
或4
.. 但事实并非如此!我仍然失去了几秒钟。另外,我自愿使用pthread_tryjoin_np()
,因为它的手册页说
pthread_tryjoin_np() 函数执行与线程的非阻塞连接
谁能给我他的帮助,我想我理解错了,但我还不能说哪一部分?基本上,为什么我在返回第一个值之前至少要进入 do while 循环四次?
编辑 1:
再次阅读文档 HOWTO 后,我突出显示以下几行:
数据等待检查和读取这两个块的事实意味着,如果您的应用程序必须处理除 GPS 之外的其他输入源,您可能必须在 gps_data 结构上使用互斥锁隔离线程中的读取循环.
我有点困惑。它的真正含义是什么?