一:何为read阻塞
read( ) 函数 —— 终端输入设备的阻塞与非阻塞的设置
read的相关属性 EAGAIN The file descriptor fd refers to a file other than a socket and has been marked non-blocking (O_NONBLOCK), and the write would block. 中文翻译 如果文件描述符不是socket的话,该函数是非阻塞的,否则该函数是阻塞的。 说明 CAN通信为socket时为阻塞 会使得线程卡住
二:如何设置为非阻塞
fcntl ( lFdCan, F_SETFL , FNDELAY ) ;
三:代码示例
main ( int argc, char * argv[ ] )
{
char buff[ 100 ] ;
pthread_t lPthreadCan1;
int lFdCan;
struct ifreq lIfreq;
struct sockaddr_can lAddrCan;
struct can_frame lFrameCan;
char can_dev_name0[ 16 ] ;
char can_dev_name1[ 16 ] ;
strcpy ( can_dev_name0, "can2" ) ;
strcpy ( can_dev_name1, "can3" ) ;
if ( argc >= 5 )
{
strncpy ( can_dev_name0, argv[ 3 ] , sizeof ( can_dev_name0) ) ;
strncpy ( can_dev_name1, argv[ 4 ] , sizeof ( can_dev_name1) ) ;
}
sprintf ( buff, "ip link set can2 down " ) ;
system ( buff) ;
sprintf ( buff, "ip link set can3 down " ) ;
system ( buff) ;
sprintf ( buff, "ip link set %s up type can bitrate 800000" , can_dev_name0) ;
system ( buff) ;
sprintf ( buff, "ip link set %s up type can bitrate 800000" , can_dev_name1) ;
system ( buff) ;
pthread_create ( & lPthreadCan1, NULL , thread_can1_recive, can_dev_name1) ;
lFdCan = socket ( PF_CAN , SOCK_RAW , CAN_RAW ) ;
if ( lFdCan < 0 )
{
printf ( "%s fail: create socket\n" , can_dev_name0) ;
return - 1 ;
}
strcpy ( lIfreq. ifr_name, can_dev_name0) ;
if ( ioctl ( lFdCan, SIOCGIFINDEX , & lIfreq) )
{
printf ( "%s fail: ioctl SIOCGIFINDEX\n" , can_dev_name0) ;
goto ERROR0 ;
}
lAddrCan. can_family = AF_CAN ;
lAddrCan. can_ifindex = lIfreq. ifr_ifindex;
if ( bind ( lFdCan, ( struct sockaddr* ) & lAddrCan, sizeof ( lAddrCan) ) )
{
goto ERROR0 ;
}
fcntl ( lFdCan, F_SETFL , FNDELAY ) ;
if ( setsockopt ( lFdCan, SOL_CAN_RAW , CAN_RAW_FILTER , NULL , 0 ) )
{
printf ( "%s fail: setsockopt CAN_RAW_FILTER\n" , can_dev_name0) ;
}
while ( recive_done == 0 )
{
lFrameCan. can_id = 0x11 ;
lFrameCan. can_dlc = sprintf ( ( char * ) lFrameCan. data, "%s" , "alinx" ) ;
write ( lFdCan, & lFrameCan, sizeof ( lFrameCan) ) ;
sleep ( 1 ) ;
lFrameCan. can_id = 0x12 ;
lFrameCan. can_dlc = sprintf ( ( char * ) lFrameCan. data, "%s" , "alinxa" ) ;
write ( lFdCan, & lFrameCan, sizeof ( lFrameCan) ) ;
sleep ( 1 ) ;
}
if ( argc >= 3 )
{
sprintf ( buff, "echo ok >> %s/%s" , argv[ 1 ] , argv[ 2 ] ) ;
system ( buff) ;
}
return 0 ;
ERROR0 :
close ( lFdCan) ;
return - 2 ;
}