manhuami2007 发表于 2022-4-9 16:04

【平头哥Sipeed LicheeRV 86 Panel测评】 6-socket实现不同进程通信

<div class="parsedown-markdown">
<p>&nbsp;</p>

<h3>架构的选择</h3>

<p>前几天移植了python3.8到开发板上,python的优点是明显的,比如不用交叉编译、语法简单、有很多封装好的库。但是python上用的GUI还需要重新移植,因此放弃了。决定使用已经移植好的lvgl实现GUI。因此整体的架构是用C语言写的lvgl的进程作为显示进程,而后台进程则由python实现。后台进程的工作包括:与远程终端通信获取数据、传输控制指令等。</p>

<h3>进程间通信方式的选择</h3>

<p>如果使用这种方式的话,就需要实现lvgl进程与python后台进程的通信。虽然进程间通信有很多种方式,但是消息队列、共享内存貌似实现不了,因为没法共同操作同一个消息队列或共享内存。通过在网上搜索发现有三种方式可以实现通信:</p>

<ol>
        <li>通过共享的文件</li>
        <li>通过管道,将其中1个进程的标准输入输出改写到管道</li>
        <li>通过socket</li>
</ol>

<p>感觉还是socket比较通用和方便,因此最终选择socket实现进程间的通信。所以总体的思路如下图所示。</p>

<h3>socket进程间通信</h3>

<p>C语言版本的socket通信如下,实现了socket客户端的方式。</p>

<pre>
<code>#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;stdio.h&gt;
#include &lt;sys/un.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;

#define SOCKET_CLIENT_PATH"/tmp/client.socket"
int client_sockfd;
struct sockaddr_un lv_socket_client_addr;

void lv_socket_init_client()
{   
    client_sockfd = socket(AF_UNIX,SOCK_STREAM,0);
    lv_socket_client_addr.sun_family = AF_UNIX;
    strcpy(lv_socket_client_addr.sun_path,SOCKET_CLIENT_PATH);
}

int lv_socket_client_send_recv(char* send_str,char* recv_str)
{
    int len = sizeof(lv_socket_client_addr);
    int result;
    int i=0;
    char ch;
    result = connect(client_sockfd,(struct sockaddr*)&amp;lv_socket_client_addr,len);
    if(result == -1){
      return -1;
    }
    if(send_str != NULL){
      write(client_sockfd,send_str,strlen(send_str));
    }
    if(recv_str != NULL){
      while(read(client_sockfd,&amp;ch,1) &gt; 0){
            *(recv_str+i) = ch;
            i++;
      }
    }
    close(client_sockfd);
    return 0;
}</code></pre>

<p>python版本的socket通信如下,实现了socket服务器端的方式。</p>

<pre>
<code>import socket
import os

skt = socket.socket(socket.AF_UNIX,socket.SOCK_STREAM)
skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
conn = '/tmp/client.socket'
if os.path.exists(conn):
    os.unlink(conn)
skt.bind(conn)
skt.listen(5)
while True:
    connect,addr = skt.accept()
    with connect123:
      data = connect123.recv(1024) #recv some data
      connect123.send(bytes('temperature:'+temperature,encoding="utf8")) #send data
      connect123.close()</code></pre>

<p>两个进程共同使用的 <em>/tmp/client.socket</em> 文件描述符实现的数据通信。</p>
</div>

<p>&nbsp;</p>

Jacktang 发表于 2022-4-9 17:18

<p>C语言版本的socket通信和python版本的socket通信</p>

<p>看楼主的介绍确实是socket比较方便简洁些</p>
页: [1]
查看完整版本: 【平头哥Sipeed LicheeRV 86 Panel测评】 6-socket实现不同进程通信