【发布时间】:2018-03-13 17:44:04
【问题描述】:
首先看下面的编辑部分。
我将 beaglebone black、ker 3.8 和 GCC 编译器用于信号处理项目。 我通过 uart 通信异步接收来自三个 GPS 模块的原始数据。因此,我使用了 3 个线程来连续检查 3 个 UART(BB-UART1、BB-UART2、BB-UART4)来接收原始数据,这里称为“读取线程”。从每个模块收到每个数据包后,我对收到的数据包进行解码并提取重要数据包。 当在线程中完成解码时,我在一个单独的线程中执行信号处理,称为“信号处理线程”,使用上述 3 个重要的解码数据包。 很明显,我应该将读取线程与信号处理线程同步。我为此使用 pthread_cond_wait 和 pthread_cond_signal。 代码运行良好,同步和信号处理高效执行。每个数据包在 0.1 秒内收到(每秒 10 次)。 在信号处理线程中,经过信号处理后,我将信号处理结果通过单独的UART,BB-UART5发送给用户。 当我添加这部分代码时,“THIS”行,一段时间后,所有部分或 OK 和信号处理结果都发送给用户,信号处理线程被冻结并锁定在互斥锁中。事实上,互斥锁解锁不是在上一步中执行的。 我花了很多时间,几个星期,来寻找原因。当我删除用于线程同步的互斥锁和其他工具(以使整个代码易于调试)时,某处的数据数组溢出并且其数据更改为溢出值。但是,当我不添加“THIS”行时,任何时候都不会发生溢出。 当我在信号处理线程中删除“写入”功能(BB-UART5)时,所有操作都正常。
信号处理线程:
void *signal_processing_thread (void *arg){
int i, j;
char str[512];
printf("000000000000000000000000000000000000000000\r\n");
printf("0-signal_processing_thread is running!\r\n");
printf("000000000000000000000000000000000000000000\r\n");
while(1){
pthread_mutex_lock(&th1); // the code lock here after add "THIS" line
pthread_mutex_lock(&th2);
pthread_mutex_lock(&th3);
if ((!decode_completed[0])|(!decode_completed[1])|(!decode_completed[2])){
pthread_mutex_unlock(&th1);
pthread_mutex_unlock(&th2);
pthread_mutex_unlock(&th3);
continue;
}
// data packets are ready in reading threads
// signal processing start
// signal processing done
// send the results
sprintf (str,"some string\r\n\0",some variables);
printf (str);
for (i=0;i<256;i++)
if (str[i]==0)
break;
write (uart5_id, str, i); // "THIS" line
decode_completed [0] = 0;
decode_completed [1] = 0;
decode_completed [2] = 0;
pthread_cond_signal(&cv1);
pthread_mutex_unlock(&th1);
pthread_cond_signal(&cv2);
pthread_mutex_unlock(&th2);
pthread_cond_signal(&cv3);
pthread_mutex_unlock(&th3);
}
printf("signal processing thread is closed!\r\n");
}
阅读线程:
void *getdecodedata1_thread (void *arg){
int ret, count, count_decode=0;
char buffer[2024], buffer_decode[2024];
int i;
printf("1-getdecodedata_thread is running!\r\n");
count = 0;
pthread_mutex_lock(&th1);
while(1){
for (i=0;i<500;i++){
ret = read(uart1_id, buffer+count ,255);
if (ret<1)
continue;
// data received
count += ret;
if (count>1000) break;
}
if (count>0){ // packet received
for (i=0;i<count;i++)
buffer_decode1[count_decode3+i]=buffer[i];
count_decode1 += count;
if (count_decode1>15){
// decode
// ....
// decode done
}
count = 0;
}
if (decode is completed) {
decode_completed [0] = 1; // newdata
printf("WAIT_1\n");
pthread_cond_wait(&cv1,&th1);
pthread_mutex_unlock(&th1);
pthread_mutex_lock(&th1);
printf("RELEASE_1\n");
}
}
}
void *getdecodedata2_thread (void *arg){
int ret, count, count_decode=0;
char buffer[2024], buffer_decode[2024];
int i;
printf("2-getdecodedata_thread is running!\r\n");
count = 0;
pthread_mutex_lock(&th2);
while(1){
for (i=0;i<500;i++){
ret = read(uart2_id, buffer+count ,255);
if (ret<1)
continue;
// data received
count += ret;
if (count>1000) break;
}
if (count>0){ // packet received
for (i=0;i<count;i++)
buffer_decode3[count_decode2+i]=buffer[i];
count_decode2 += count;
if (count_decode2>15){
// decode
// ....
// decode done
}
count = 0;
}
if (decode is completed) {
decode_completed [1] = 1; // newdata
printf("WAIT_2\n");
pthread_cond_wait(&cv2,&th2);
pthread_mutex_unlock(&th2);
pthread_mutex_lock(&th2);
printf("RELEASE_2\n");
}
}
}
void *getdecodedata3_thread (void *arg){
int ret, count, count_decode=0;
char buffer[2024], buffer_decode[2024];
int i;
printf("3-getdecodedata_thread is running!\r\n");
count = 0;
pthread_mutex_lock(&th3);
while(1){
for (i=0;i<500;i++){
ret = read(uart4_id, buffer+count ,255);
if (ret<1)
continue;
// data received
count += ret;
if (count>1000) break;
}
if (count>0){ // packet received
for (i=0;i<count;i++)
buffer_decode3[count_decode3+i]=buffer[i];
count_decode3 += count;
if (count_decode3>15){
// decode
// ....
// decode done
}
count = 0;
}
if (decode is completed) {
decode_completed [2] = 1; // newdata
printf("WAIT_3\n");
pthread_cond_wait(&cv3,&th3);
pthread_mutex_unlock(&th3);
pthread_mutex_lock(&th3);
printf("RELEASE_3\n");
}
}
}
编辑:我发现问题出在代码的另一个地方。在某些地方我使用“写入”功能将一些字节发送到 UART5,并在一个单独的线程中我同时读取(非阻塞)UART5 以接收命令。我认为出现了“SegFault”之类的问题,并且看到了上述问题。当我评论 UART5 的“读取”功能时,一切正常,互斥锁工作正常。如何使用UART5同时读写?
【问题讨论】:
标签: multithreading overflow mutex uart