Непрерывная программа Bluetooth C с использованием потоков
Я пытаюсь отправить свои измерительные данные (температура, влажность и давление) по Bluetooth, и они должны быть непрерывными, поэтому я использую нити для этого, но это становится слишком сложным для меня.
Вот код клиента Bluetooth:
#include "defines.h"
void L2CAP_client(char *b_addr, float *temp, float *humi, float *pressure)
{
struct sockaddr_l2 addr = { 0 };
struct Measurement_Data *Thread_Data = malloc(sizeof(struct Measurement_Data));
int s, status;
char dest[18];
pthread_t Measurement_data_thread = 0;
int iret = 0;
pthread_t Thread_id;
strncpy(dest, b_addr, 18);
// allocate a socket
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
Thread_Data->s_ptr = s;
// set the connection parameters (who to connect to)
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = htobs(0x1001);
str2ba( dest, &addr.l2_bdaddr );
// connect to server
status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
Thread_Data->temp = *temp;
Thread_Data->humi = *humi;
Thread_Data->pressure = *pressure;
// send a message
if( status == 0 ) {
iret = pthread_create(&Measurement_data_thread, NULL, &Thread_Function, (void*) &Thread_Data);
if(iret != 0){
perror("Thread creation failed\n");
}
Thread_id = pthread_self();
printf("ID of Temp_thread is: %u\n", (unsigned int)Thread_id);
}
if( status < 0 ) perror("uh oh");
printf("Thread 1 returns: %d\n",iret);
pthread_join(Measurement_data_thread, NULL);
close(s);
}
void *Thread_Function(void* Measurement_Data)
{
int s = 0;
struct Measurement_Data *Thread_Data = (struct Measurement_Data*) Measurement_Data;
s = Thread_Data->s_ptr;
send(s, &Thread_Data, sizeof(Thread_Data), 0);
free(Thread_Data);
//return 0;
}
Вот код сервера Bluetooth:
#include "defines.h"
struct Measurement_Data *L2CAP_server(void)
{
struct sockaddr_l2 loc_addr = { 0 }, rem_addr = { 0 };
char buf[256] = { 0 };
int s, client, bytes_read;
int opt = sizeof(rem_addr);
static struct Measurement_Data Data;
struct Measurement_Data *Thread_Data = malloc(sizeof(struct Measurement_Data));
pthread_t Measurement_data_thread = 0;
int iret = 0;
pthread_t Thread_id;
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// bind socket to port 0x1001 of the first available
// bluetooth adapter
loc_addr.l2_family = AF_BLUETOOTH;
loc_addr.l2_bdaddr = *BDADDR_ANY;
loc_addr.l2_psm = htobs(0x1001);
bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
// put socket into listening mode
listen(s, 1);
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
Thread_Data->c_ptr = client;
ba2str( &rem_addr.l2_bdaddr, buf );
fprintf(stderr, "accepted connection from %s\n", buf);
memset(buf, 0, sizeof(buf));
iret = pthread_create(&Measurement_data_thread, NULL, &Thread_Function, (void*) &Thread_Data);
if(iret != 0){
perror("Thread creation failed\n");
}
Thread_id = pthread_self();
printf("ID of Temp_thread is: %u\n", (unsigned int)Thread_id);
printf("Thread 1 returns: %d\n",iret);
pthread_join(Measurement_data_thread, NULL);
// close connection
close(client);
close(s);
return (&Data);
}
void *Thread_Function(void* Measurement_Data)
{
int c = 0;
struct Measurement_Data *Thread_Data = (struct Measurement_Data*) Measurement_Data;
c = Thread_Data->c_ptr;
recv(c, &Thread_Data, sizeof(Thread_Data), 0);
printf("Temp: %0.1f\n", Thread_Data->temp);
printf("Humi: %0.1f\n", Thread_Data->humi);
printf("Pres: %0.1f\n", Thread_Data->pressure);
free(Thread_Data);
//return 0;
}
Он отправляет только нули, и я также получаю эту ошибку: * обнаружен glibc *./anturi_luku: munmap_chunk (): неверный указатель: 0xbef48738 ***
Прав ли я, что мне нужно использовать мьютекс для блокировки данных?
4 ответа
Теперь я получил сообщение об ошибке, чтобы исчезнуть. Это был четвертый параметр функции pthread_create. Я удалил символ амперсанда. Теперь функция выглядит следующим образом: pthread_create(&Measurement_data_thread, NULL, &Thread_Function, (void*) Thread_Data);
Но это все еще не отправка или получение каких-либо данных. Когда я использую printf для проверки этих значений данных, которые должны быть отправлены, функция thread_function заканчивается, они в порядке. Но на благотворных концах он иногда печатает только нули, а иногда ничего.
Нужен ли сейчас мьютекс для блокировки данных?
Вот отчет valgrind со стороны клиента:
==2157== Memcheck, a memory error detector
==2157== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==2157== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==2157== Command: ./anturi_luku
==2157==
Temperature: 22.7C
Humidity: 61.7%
Temperature: 22.7C
Humidity: 61.7%
pressure= 0, 0, 0
Pressure: 0.0 Pa
ID of Temp_thread is: 67241968
Thread 1 returns: 0
==2157== Thread 2:
==2157== Invalid free() / delete / delete[] / realloc()
==2157== at 0x48348B8: free (vg_replace_malloc.c:427)
==2157== by 0x8C0B: Thread_Function (L2CAP_client.c:89)
==2157== by 0x485FBFB: start_thread (pthread_create.c:306)
==2157== by 0x4962967: ??? (clone.S:116)
==2157== Address 0xbde575e8 is on thread 1's stack
==2157==
==2157==
==2157== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- n
==2157==
==2157== HEAP SUMMARY:
==2157== in use at exit: 16 bytes in 1 blocks
==2157== total heap usage: 2 allocs, 2 frees, 152 bytes allocated
==2157==
==2157== LEAK SUMMARY:
==2157== definitely lost: 16 bytes in 1 blocks
==2157== indirectly lost: 0 bytes in 0 blocks
==2157== possibly lost: 0 bytes in 0 blocks
==2157== still reachable: 0 bytes in 0 blocks
==2157== suppressed: 0 bytes in 0 blocks
==2157== Rerun with --leak-check=full to see details of leaked memory
==2157==
==2157== For counts of detected and suppressed errors, rerun with: -v
==2157== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 6)
Valgrind является очень полезным инструментом в таких ситуациях. Удалось ли вам использовать Valgrind? Можете ли вы поделиться отчетом Valgrind.
Убедитесь, что вы используете опцию 'db-attach', поскольку Valgrind будет останавливаться после каждой отображаемой ошибки и печатает строку. Попробуйте использовать следующую команду, заменив a.out именем вашего файла.
$ valgrind --tool = memcheck --db-attach = yes./a.out
Рад, что вы можете получить отчет Valgrind для клиента Bluetooth L2CAP на языке C поверх ARM.
Как видите, при первой ошибке вам будет предложено следующее.
---- Присоединиться к отладчику? --- [Возврат / Н / Н / Г / Г / С / С] ----
Нажатие Ret или N Ret или n Ret заставляет Valgrind не запускать отладчик для этой ошибки.
Нажатие Y Ret или y Ret заставляет Valgrind запустить отладчик для программы на этом этапе.
Из журналов видно, что используется "n". Удалось ли вам попробовать "Y"?
Кроме того, из журналов, кажется, сообщают, что сделано недействительное free. В дополнение к этому, кажется, что free() вызывается на нераспределенной памяти. Проверь это.