91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

虛擬機串口與主機串口通信·小程序(下)

發布時間:2020-08-10 11:39:39 來源:網絡 閱讀:1159 作者:SherryX 欄目:系統運維

上次說到的,不能做到實時通信。那么開兩個進程就可以了,一個用來監聽是否有消息傳來,一個用來等待用戶輸入。那么,先來復習一下進程的相關概念。
<br>

進程結構

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

注意:
<br>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;
}
*/

運行結果:
虛擬機串口與主機串口通信·小程序(下)
<br>發現問題了沒?對的。父進程會先死。
程序運行時:
虛擬機串口與主機串口通信·小程序(下)
程序結束時:
虛擬機串口與主機串口通信·小程序(下)

如何解決呢?下次說~

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

定襄县| 安义县| 全椒县| 自贡市| 田东县| 横山县| 封开县| 原平市| 竹山县| 金湖县| 南召县| 永寿县| 和龙市| 高密市| 营山县| 吴忠市| 车险| 延安市| 双桥区| 大足县| 汉中市| 东乌| 台安县| 揭东县| 古丈县| 武川县| 大同县| 高阳县| 阿拉善盟| 铁力市| 平原县| 奉新县| 绥中县| 河津市| 喜德县| 宜昌市| 遵化市| 白河县| 谷城县| 葵青区| 盈江县|