我们专注攀枝花网站设计 攀枝花网站制作 攀枝花网站建设
成都网站建设公司服务热线:400-028-6601

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

虚拟机串口与主机串口通信·小程序(下)

系统运维

上次说到的,不能做到实时通信。那么开两个进程就可以了,一个用来监听是否有消息传来,一个用来等待用户输入。那么,先来复习一下进程的相关概念。

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册、网页空间、营销软件、网站建设、七星网站维护、网站推广。进程结构

linux中进程包含PCB(进程控制块)、程序以及程序所操纵的数据结构集,可分为“代码段”、“数据段”和“堆栈段”。

进程状态

运行状态R(TASK_RUNNING)

可中断睡眠状态S(TASK_INTERRUPTIBLE)
不可中断睡眠状态D(TASK_UNINTERRUPTIBLE)

暂停状态T(TASK_STOPPED或TASK_TRACED)

僵死状态Z(TASK_ZOMBIE)
退出状态X(TASK_DEAD)
ps -aux 查看进程信息,可以看到各进程的状态:

init进程

所有进程的父进程
init进程绝不会终止。

它是一个普通的用户进程(与交换进程不同,它不是内核中的系统进程),但是它以超级用户特权运行。

获取进程标识

#include < sys/types.h>
#include < unistd.h>
pid_t getpid(void); 返回:调用进程的进程I D
pid_t getppid(void); 返回:调用进程的父进程I D
uid_t getuid(void); 返回:调用进程的实际用户I D
uid_t geteuid(void); 返回:调用进程的有效用户I D
gid_t getgid(void); 返回:调用进程的实际组I D
gid_t getegid(void); 返回:调用进程的有效组I D

fork系统调用
#include < sys/types.h>
#include < unistd.h>
    pid_t fork(void);
    返回:子进程中为0,父进程中为子进程I D,出错为-1

注意:

1、使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:
进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。

2、子进程与父进程的区别在于:
1)父进程设置的锁,子进程不继承
2)各自的进程ID和父进程ID不同
3)子进程的未决告警被清除;
4)子进程的未决信号集设置为空集。

3、fork系统调用之后,父子进程将交替执行。
4、如果父进程先退出,子进程还没退出。那么子进程的父进程将变为init进程。(注:任何一个进程都必须有父进程)
5、如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵进程。(这是不好的,这样子进程会一直占用内存资源)
解决办法:
1)wait函数:使父进程阻塞,直到一个子进程结束或者该进程收到一个指定信号为止。(但是,这样不好)
2)signal(SIGCHLD,SIG_IGN)。表示父进程忽略SIGCHLD,该信号是子进程退出的时候向父进程发出的,由init进程收。

测试

接下来,可以继续我们上次的小程序了。

#include < stdio.h>
#include < sys/types.h>
#include < signal.h>
#include  port.h
#include  readConfig.h

// 1、主机与虚拟机 
int main()
{
    int fd,pid,child_id;
    char filename[20] = serial.cfg;
    char recbuf[100] = ;
    char sendbuf[100] = ;

    struct t_port port = {0};

    //从文件获取配置信息
    getMsg(filename,&port);
    //串口初始化
    fd = portInit(port.devname,port.speed,port.data,port.parity,port.stop);

    //主机与虚拟机串口通信
    pid = fork();
    if(pid == -1)
    {
        perror(create process);
        return 1;
    }

    else if(pid == 0) //子进程 接收消息
    {
        child_id = getpid();
        while(read(fd,recbuf,100)>0)  //这里不能用strlen。因为开始strlen(recbuf)=0
        {
            if(strcmp(recbuf,) != 0)
            {
                printf(receive msg: %s\\n,recbuf);
                putchar(\'$\');
                fflush(stdout);
            }
            memset(recbuf,0,100);
        }

    }
    else    //(主)父进程 发送消息
    {
        printf($);
        while(1)
        {
            memset(sendbuf,0,100);
            scanf(%s,sendbuf);
            if(strcmp(sendbuf,over) == 0) //但是,此时,子进程未结束,还在后台运行
            {
                break;
            }
            if(write(fd,sendbuf,strlen(sendbuf)) > 0)
            {
                printf($);
            }
        }

    }

    close(fd);
    return 0;
}

//2、虚拟机两串口
/*
int main(int argc,char *argv[])
{
    int fd,pid;
    char receivebuf[100] = ;
    char sendbuf[100] = ;

    if(argc != 2)
    {
        printf(format error!\\n);
        return 1;
    }

    if( strcmp(argv[1],ttyS0)==0)
    {
        fd = portInit(/dev/ttyS0,115200,8,0,1);
    }
    else if(strcmp(argv[1],ttyS1)==0)
    {
        fd = portInit(/dev/ttyS1,115200,8,0,1);
    }
    else 
    {
        printf(format error!\\n);
        return 1;
    }

    pid = fork();

    if(pid == -1)
    {
        perror(create process);
        return 1;
    }
    else if(pid == 0) //子进程
    {
        //接收消息
        while(read(fd,receivebuf,sizeof(receivebuf)) > 0)
        {
            if(strcmp(receivebuf,) != 0)
            {
                printf(receive msg : %s\\n,receivebuf);
            }
            memset(receivebuf,0,100);
        }

    }

    else    //父进程
    {
        //发送消息
        while(1)
        {
            memset(sendbuf,0,100);
            scanf(%s,sendbuf);
            if(strcmp(sendbuf,-over) == 0)
            {
                break;
            }
            write(fd,sendbuf,strlen(sendbuf));
            printf(send OK\\n);
        }
    }

    close(fd);
    return 0;
}
*/

运行结果:


发现问题了没?对的。父进程会先死。
程序运行时:

程序结束时:

如何解决呢?下次说~


分享题目:虚拟机串口与主机串口通信·小程序(下)
浏览路径:http://shouzuofang.com/article/cgsodh.html

其他资讯