是高手就进来帮帮忙!ARM9(2440)多线程串口编程,运行异常:gnu_cxx:concurrence_broadcast_error

是高手就进来帮帮忙!ARM9(2440)多线程串口编程,运行错误:__gnu_cxx::__concurrence_broadcast_error
在ARM9运行多线程串口程序是抛出这样的异常:terminate called after throwing an instance of '__gnu_cxx::__concurrence_broadcast_error'
  what(): __gnu_cxx::__concurrence_broadcast_error

只要以调用OpenPort就报错。

该源代码在Fedora9上编译、运行都没问题,程序中用了网上找到的一个多线程串口类。
编译器用的是gcc 4.4.3

Google、百度边了也没找到解决方法,各位有什么解决方法或思路不?
希望大家能帮帮忙,多谢!!!!!!!!

C/C++ code

//主程序
#include "CSerial.h"
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    CSerial::CSerial serial;
    serial.OpenPort("/dev/ttySAC0", 115200, 8, 1, 'N');//报错!!

    while(1);

    return 0;
}



C/C++ code

/*自定义串口类
* CSerial.h
*
*  Created on: 2010-7-20
*      Author: yzm
*/

#ifndef CSERIAL_H_
#define CSERIAL_H_
#include      <pthread.h>
#include      <time.h>
#include      <stdio.h>
#include     <sys/types.h>
#include     <sys/stat.h>
#include     <fcntl.h>      /*文件控制定义*/
#include     <termios.h>    /*PPSIX 终端控制定义*/
#include     <errno.h>      /*错误号定义*/
#include      <string.h>
#include     <string>
#include      "CCriticalSection.h"

using namespace std;

#define      BUFFER_LENGTH 1024

namespace CSerial {
class CSerial
{
private:
    string m_PortName;
    int  m_baudrate;
    int m_databits;
    int m_stopbits;
    char m_parity;
     //通讯线程标识符ID
     pthread_t      m_thread;
     CCriticalSection  mutex;
     // 串口数据接收线程
     static void* ReceiveThreadFunc( void* lparam );
public:
     CSerial();
     virtual ~CSerial();
     // 已打开的串口文件描述符
     int                m_fd;
     int                m_DatLen;
     unsigned char      DatBuf[BUFFER_LENGTH];
     int                m_ExitThreadFlag;
     // 按照指定的串口参数打开串口,并创建串口接收线程
     int OpenPort( string PortName, int baudrate, int databits, int stopbits, char parity );
     // 关闭串口并释放相关资源
     int ClosePort( );
     // 向串口写数据
     int WritePort( unsigned char* Buf, int len );
     // 接收串口数据处理函数
     virtual int PackagePro( unsigned char* Buf, int len );
private:
    void set_speed(int fd, int speed);
    int  set_Parity(int fd,int databits,int stopbits,int parity);
};

}

#endif /* CSERIAL_H_ */



C/C++ code

/*
* CSerial.cpp
*
*  Created on: 2010-7-20
*      Author: yzm
*/

#include "CSerial.h"
#include <sys/select.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>     /*Unix 标准函数定义*/

namespace CSerial {
int speed_arr[] = {B115200,B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400,
        B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {115200,38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200,
        9600, 4800, 2400, 1200, 300, };
string BYTE2HEX(unsigned char* buffer,int nSize)
{
    char buf[1024];
    memset(buf,0,1024);
    int len = 0;
    for(int i = 0;i < nSize;i++)
    {
        int tmp = sprintf(buf + len,"%02x ",buffer);
        len += tmp;
    }
    string str(buf);
    return str;
}
CSerial::CSerial()
{
    m_ExitThreadFlag = false;
    m_PortName = "/dev/ttyS0";
    m_baudrate = 2400;
    m_databits = 8;
    m_stopbits = 1;
    m_parity = 'e';
}
CSerial::~CSerial()
{
    ClosePort( );
}
int CSerial::OpenPort(string PortName, int baudrate, int databits,
        int stopbits, char parity) {
    /*以读写方式打开串口*/
    m_fd = open(PortName.data(), O_RDWR);
    if (-1 == m_fd) {
        /* 不能打开串口一*/
        perror(" 提示错误!");
        return -1;
    } else {
        m_PortName = PortName;
        m_baudrate = baudrate;
        m_databits = databits;
        m_stopbits = stopbits;
        m_parity = parity;
        //设置参数
        set_speed(m_fd, baudrate);
        set_Parity(m_fd, databits, stopbits, parity);

        pthread_create(&m_thread,NULL,CSerial::CSerial::ReceiveThreadFunc,this);
        return 1;
    }
}
int CSerial::ClosePort( )
{
     m_ExitThreadFlag = true;
     close(m_fd);
     pthread_join(m_thread,NULL);
     return 1;
}
int CSerial::PackagePro( unsigned char* Buf, int len )
{
    string str = BYTE2HEX(Buf,len);
    printf("%s\r\n",str.data());
    WritePort(Buf,len);
    return 1;
}
void* CSerial::ReceiveThreadFunc(void* lparam) {
    CSerial *pSer = (CSerial*) lparam;
    fd_set fdRead;
    int ret;
    struct timeval aTime;
    while (1) {
        //收到退出事件,结束线程
        //printf("Thread...\r\n");
        if (pSer->m_ExitThreadFlag) {
            break;
        }
        FD_ZERO(&fdRead);
        FD_SET(pSer->m_fd,&fdRead);
        aTime.tv_sec = 2;
        aTime.tv_usec = 100;
        ret = select(pSer->m_fd + 1, &fdRead, NULL, NULL, &aTime);
        if (ret < 0) {
            //关闭串口
            pSer->ClosePort();
            break;
        }
        if (ret > 0) {
            //判断是否读事件
            if (FD_ISSET(pSer->m_fd,&fdRead)) {
                //data available, so get it!
                pSer->m_DatLen = read(pSer->m_fd, pSer->DatBuf, BUFFER_LENGTH);
                // 对接收的数据进行处理,这里为简单的数据回发
                if (pSer->m_DatLen > 0) {
                    pSer->PackagePro(pSer->DatBuf, pSer->m_DatLen);
                }
                // 处理完毕
            }
        }
    }
    printf("ReceiveThreadFunc finished\n");
    pthread_exit(NULL);
    return 0;
}
/**
*@brief  设置串口通信速率
*@param  fd     类型 int  打开串口的文件句柄
*@param  speed  类型 int  串口速度
*@return  void
*/
void CSerial::set_speed(int fd, int speed) {
    unsigned int i;
    int status;
    struct termios Opt;
    tcgetattr(fd, &Opt);
    for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {
        if (speed == name_arr) {
            tcflush(fd, TCIOFLUSH);
            cfsetispeed(&Opt, speed_arr);
            cfsetospeed(&Opt, speed_arr);
            status = tcsetattr(fd, TCSANOW, &Opt);
            if (status != 0) {
                perror("tcsetattr fd1");
                return;
            }
            tcflush(fd, TCIOFLUSH);
        }
    }
}
/**
*@brief   设置串口数据位,停止位和效验位
*@param  fd     类型  int  打开的串口文件句柄
*@param  databits 类型  int 数据位   取值 为 7 或者8
*@param  stopbits 类型  int 停止位   取值为 1 或者2
*@param  parity  类型  int  效验类型 取值为N,E,O,,S
*/
int CSerial::set_Parity(int fd, int databits, int stopbits, int parity) {
    struct termios options;
    if (tcgetattr(fd, &options) != 0) {
        perror("SetupSerial 1");
        return (false);
    }
    options.c_cflag &= ~CSIZE;
    switch (databits) /*设置数据位数*/
    {
    case 7:
        options.c_cflag |= CS7;
        break;
    case 8:
        options.c_cflag |= CS8;
        break;
    default:
        fprintf(stderr, "Unsupported data size\n");
        return (false);
    }
    switch (parity) {
    case 'n':
    case 'N':
        options.c_cflag &= ~PARENB; /* Clear parity enable */
        options.c_iflag &= ~INPCK; /* Enable parity checking */
        break;
    case 'o':
    case 'O':
        options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
        options.c_iflag |= INPCK; /* Disnable parity checking */
        break;
    case 'e':
    case 'E':
        options.c_cflag |= PARENB; /* Enable parity */
        options.c_cflag &= ~PARODD; /* 转换为偶效验*/
        options.c_iflag |= INPCK; /* Disnable parity checking */
        break;
    case 'S':
    case 's': /*as no parity*/
        options.c_cflag &= ~PARENB;
        options.c_cflag &= ~CSTOPB;
        break;
    default:
        fprintf(stderr, "Unsupported parity\n");
        return (false);
    }
    /* 设置停止位*/
    switch (stopbits) {
    case 1:
        options.c_cflag &= ~CSTOPB;
        break;
    case 2:
        options.c_cflag |= CSTOPB;
        break;
    default:
        fprintf(stderr, "Unsupported stop bits\n");
        return (false);
    }

    options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN);  /*Input*/

    options.c_iflag  &= ~(IXON | IXOFF | IXANY);//关流控
    options.c_iflag  &= ~(INLCR | IGNCR | ICRNL | IUCLC | IGNBRK|BRKINT|PARMRK|ISTRIP);

    options.c_oflag  &= ~(ONLCR | OCRNL | ONLRET | ONOCR | OLCUC | OFILL | CRTSCTS);
    options.c_oflag  &= ~OPOST;   /*Output*/

    /* Set input parity option */
    if (parity != 'n')
        options.c_iflag |= INPCK;
    tcflush(fd, TCIFLUSH);
    options.c_cc[VTIME] = 50; /* 设置超时15 seconds*/
    options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
    if (tcsetattr(fd, TCSANOW, &options) != 0) {
        perror("SetupSerial 3");
        return (false);
    }
    return (true);
}
int CSerial::WritePort( unsigned char* Buf, int len )
{
    mutex.Lock();
    int ToWrite = len;
    int hasWrite = 0;
    int wPos = 0;
    while(ToWrite > 0){
        hasWrite = write(m_fd, Buf + wPos, ToWrite);
        if(hasWrite <= 0)break;
        ToWrite -= hasWrite;
        wPos += hasWrite;
    }
    mutex.Unlock();
    return len - ToWrite;
}
}