• Linux 7:mybash的实现和进程间通信



    一、bash是什么?

    1.内置命令

    内置命令不可以通过fork+exec方式实现,所以不能用bash
    cd 改变当前工作路径
    exit

    在这里插入图片描述

    2. 实现mybash

    mybash.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<sys/wait.h>
      6 #include<pwd.h>
      7 
      8 #define ARG_MAX 10
      9 char* get_cmd(char buff[],char* myargv[])//解析命令
     10 {
     11     if(buff==NULL||myargv==NULL)
     12     {
     13         return NULL;
     14     }
     15 
     16     int i=0;//数组下标
     17     char*s=strtok(buff," ");
     18     while(s!=NULL)
     19     {
     20         myargv[i++]=s;
     21         s=strtok(NULL," ");
     22     }
     23     return myargv[0];
     24 }
     25 void run_cmd(char* path,char* myargv[])
     26 {
     27     if(path==NULL)
     28     {
     29         return;
     30     }
     31     pid_t pid=fork();
     32     if(pid==-1)
     33     {
     34         return;
     35     }
     36     if(pid==0)
     37     {
     38         execvp(path,myargv);
     39         perror("cmd err");//执行失败,退出子进程
     40         exit(0);
     41     }
     42     wait(NULL);
     43 }
     44 void printf_info()//打印提示符
     45 {
     46     char* user_str="$";
     47     char* source_info="mybash1.0 >>";
     48     int uid = getuid();
     49     if(uid == 0)
     50     {
     51         user_str = "#";
     52     }
     53     struct passwd* ptr=getpwuid(uid);
     54     if(ptr==NULL)
     55     {
     56         printf("%s",source_info);
     57         fflush(stdout);
     58         return;
     59     }
     60     char hostname[128]={0};
     61     if(gethostname(hostname,128)==-1)
     62     {
     63         printf("%s",source_info);
     64         fflush(stdout);
     65         return;
     66     }
     67 
     68     char pwd_str[256]={0};
     69     if(getcwd(pwd_str,256)==NULL)
     70     {
     71 
     72         printf("%s",source_info);
     73         fflush(stdout);
     74         return;
     75     }
     76 
     77     printf("\033[1;32m%s@%s\033[0m:\033[1;34m%s\033[0m%s ",ptr->pw_name,hostname,pwd_str,user_str);
     78     fflush(stdout);
     79 }
     80 int main()
     81 {
     82     while(1)
     83     {
     84         //printf("maria@ubantu: ~]$");
     85         //fflush(stdout);
     86 
     87         char buff[128]={0};
     88         printf_info();
     89         fgets(buff,128,stdin);
     90         buff[strlen(buff)-1]=0;
     91         char* myargv[ARG_MAX]={0};
     92         char* cmd=get_cmd(buff,myargv);
     93         if(cmd==NULL)
     94         {
     95             continue;
     96         }
     97         else if(strcmp(cmd,"exit")==0)
     98         {
     99             break;
    100         }
    101         else if(strcmp(cmd,"cd")==0)
    102         {
    103             if(myargv[1]==NULL)
    104             {
    105                 continue;
    106             }
    107 
    108             if(chdir(myargv[1])==-1)
    109             {
    110                 perror("cd err:");
    111             }
    112         }
    113         else
    114         {
    115             run_cmd(cmd,myargv);
    116         }
    117     }
    118     exit(0);
    119 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    运行结果

    在这里插入图片描述

    3. 实现pwd,ls命令

    pwd.c
    在这里插入图片描述
    运行结果
    在这里插入图片描述

    ls.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<unistd.h>
      4 #include<dirent.h>
      5 #include<string.h>
      6 #include<sys/stat.h>
      7 int main(int argc,char* argv[])
      8 {
      9     char curr_dir[256]={0};
     10     if(argc==2)
     11     {
     12         strcpy(curr_dir,argv[1]);
     13     }
     14     else
     15     {
     16         if(getcwd(curr_dir,256)==NULL)
     17         {
     18             printf("ls err\n");
     19             exit(1);
     20         }
     21     }
     22 
     23     DIR* p=opendir(curr_dir);//传入位置参数
     24     struct dirent* s=NULL;//从文件目录中读取文件属性
     25     struct stat st;
     26     while((s=readdir(p))!=NULL)//非隐藏文件
     27     {
     28         if(strncmp(s->d_name,".",1)==0)
     29         {
     30             continue;
     31         }
     32         if(lstat(s->d_name,&st)==-1)//文件属性,类型,大小,权限,属主
     33         {
     34             printf("%s  ",s->d_name);
     35             continue;
     36         }
     37         if(S_ISDIR(st.st_mode))//判断是否为目录文件
     38         {
     39             printf("\033[1;32m%s\033[0m  ",s->d_name);
     40         }
     41         else if(S_ISFIFO(st.st_mode))//判断是否为管道文件
     42         {
     43             printf("\033[40;33m%s\033[0m  ",s->d_name);
     44         }
     45         else//普通文件
     46         {
     47             //具有执行权限-绿,有执行权限-黑色
     48             if(st.st_mode&(S_IXUSR|S_IXGRP|S_IXOTH))
     49             {
     50                 printf("\033[1;32m%s\033[0m  ",s->d_name);
     51             }
     52             else
     53             {
     54                 printf("%s:%ld  ",s->d_name,st.st_size);
     55             }
     56         }
     57     }
     58     printf("\n");
     59 
     60     closedir(p);
     61     exit(0);
     62 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    运行结果
    在这里插入图片描述

    mybah.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<sys/wait.h>
      6 #include<pwd.h>
      7 
      8 
      9 #define PATH_BIN "/home/maria/c215/20220523/mybin/"
     10 #define ARG_MAX 10
     11 char* get_cmd(char buff[],char* myargv[])//解析命令
     12 {
     13     if(buff==NULL||myargv==NULL)
     14     {
     15         return NULL;
     16     }
     17 
     18     int i=0;//数组下标
     19     char*s=strtok(buff," ");
     20     while(s!=NULL)
     21     {
     22         myargv[i++]=s;
     23         s=strtok(NULL," ");
     24     }
     25     return myargv[0];
     26 }
     27 void run_cmd(char* path,char* myargv[])
     28 {
     29     if(path==NULL)
     30     {
     31         return;
     32     }
     33     pid_t pid=fork();
     34     if(pid==-1)
     35     {
     36         return;
     37     }
     38     if(pid==0)
     39     {
     40         char path_name[128]={0};
     41         if(strncmp(path,"/",1)==0||strncmp(path,"./",2)==0)
     42         {
     43             strcpy(path_name,path);
     44         }
     45         else
     46         {
     47             strcpy(path_name,PATH_BIN);
     48             strcat(path_name,path);
     49         }
     50         execv(path_name,myargv);
     51         //execvp(path,myargv);
     52         perror("cmd err");//执行失败,退出子进程
     53         exit(0);
     54     }
     55     wait(NULL);
     56 }
     57 void printf_info()//打印提示符
     58 {
     59     char* user_str="$";
     60     char* source_info="mybash1.0 >>";
     61     int uid = getuid();
     62     if(uid == 0)
     63     {
     64         user_str = "#";
     65     }
     66     struct passwd* ptr=getpwuid(uid);
     67     if(ptr==NULL)
     68     {
     69         printf("%s",source_info);
     70         fflush(stdout);
     71         return;
     72     }
     73     char hostname[128]={0};
     74     if(gethostname(hostname,128)==-1)
     75     {
     76         printf("%s",source_info);
     77         fflush(stdout);
     78         return;
     79     }
     80 
     81     char pwd_str[256]={0};
     82     if(getcwd(pwd_str,256)==NULL)
     83     {
     84 
     85         printf("%s",source_info);
     86         fflush(stdout);
     87         return;
     88     }
     89 
     90     printf("\033[1;32m%s@%s\033[0m:\033[1;34m%s\033[0m%s ",ptr->pw_name,hostname,pwd_str,user_str);
     91     fflush(stdout);
     92 }
     93 int main()
     94 {
     95     while(1)
     96     {
     97         //printf("maria@ubantu: ~]$");
     98         //fflush(stdout);
     99 
    100         char buff[128]={0};
    101         printf_info();
    102         fgets(buff,128,stdin);
    103         buff[strlen(buff)-1]=0;
    104         char* myargv[ARG_MAX]={0};
    105         char* cmd=get_cmd(buff,myargv);
    106         if(cmd==NULL)
    107         {
    108             continue;
    109         }
    110         else if(strcmp(cmd,"exit")==0)
    111         {
    112             break;
    113         }
    114         else if(strcmp(cmd,"cd")==0)
    115         {
    116             if(myargv[1]==NULL)
    117             {
    118                 continue;
    119             }
    120 
    121             if(chdir(myargv[1])==-1)
    122             {
    123                 perror("cd err:");
    124             }
    125         }
    126         else
    127         {
    128             run_cmd(cmd,myargv);
    129         }
    130     }
    131     exit(0);
    132 }    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132

    运行结果(拼接路径)
    在这里插入图片描述

    cp

    如何复制文件夹到新的文件夹内?

    首先在要复制到的新文件夹内创建一个新文件夹,然后命名为要复制的文件夹名字,之后再把要复制文件夹里面的内容拷贝到新文件夹

    二、进程间通信

    1. 进程间通信方式(同一台主机)

    • 管道
    • 信号量
    • 共享内存
    • 消息队列
    • 套接字(QQ)

    2. 管道

    管道可以用来在两个进程之间传递数据,如: ps -ef | grep “bash”, 其中‘|’就是管道,其作用就是将 ps 命令的结果写入管道文件,然后 grep 再从管道文件中读出该数据进行过滤。
    在这里插入图片描述

    2.1 有名管道

    有名管道可以在任意两个进程之间通信
    有名管道的创建:
    ◼ 命令创建: mkfifo FIFO
    在这里插入图片描述
    ◼ 系统调用创建
    在这里插入图片描述
    管道通信必须在两个进程之间进行,如果在一端,则会发生阻塞

    2.1.1 写端关闭(返回值为0),读端也自动结束进程关闭

    在这里插入图片描述
    在这里插入图片描述

    2.1.2 读端关闭,写端异常终止

    在这里插入图片描述

    2.1.3 通讯方式

    • 单工: 通信方向固定(收音机)
    • 半双工:通信方向可以逆转,但是只允许一方讲话(对讲机)
    • 全工:打电话

    2.1.4 管道特点

    • 向管道中写入的数据在内存中
    • 通讯方式半双工
    • 若管道满,则写操作阻塞;若管道为空,读操作阻塞

    2.1.5 有名管道和无名管道区别?

    有名管道可以在任意两个进程之间通信,而无名管道只能在父子进程之间通信

    2.2 无名管道

    在这里插入图片描述
    main.c
    在这里插入图片描述
    ./main
    在这里插入图片描述
    在这里插入图片描述

    3. 信号量

    信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目,获取资源时,需要对信号量的值进行原子减一,该操作被称为 P 操作。当信号量值为 0 时,代表没有资源可用,P 操作会阻塞。释放资源时,需要对信号量的值进行原子加一,该操作被称为 V操作。信号量主要用来同步进程。信号量的值如果只取 0,1,将其称为二值信号量。如果信号量的值大于 1,则称之为计数信号量。

    3.1 特点

    • 信号量是一种特殊变量(取正数值)
    • 计数信号量:减一:代表获取资源(P操作),加一:代表释放资源(V操作)原子操作
    • 同步进程
    • 临界区:同一时刻,只允许一个进程访问/操作的资源
    • 临界资源:访问临界资源的代码段
    semget()创建信号量,或获取一个已存在的信号量
    semop()实现p,v操作
    semctl()初始化,销毁

    3.2 ipcs/ipcrm

    ipcs查看系统中的消息队列
    ipcrm删除

    ipcs 可以查看消息队列、共享内存、信号量的使用情况,使用 ipcrm 可以进行删除操作

    在这里插入图片描述
    在这里插入图片描述

    4. 共享内存

    4.1 共享内存原理

    共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进程向共享内存写入了数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。由于它并未提供同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。
    在这里插入图片描述
    物理内存共用,把物理内存映射到a的地址空间之中,然后再映射到B的地址中去。

    1. #include <sys/ipc.h>
    2. #include <sys/shm.h>
    3. #include <sys/types.h>
    /*
    6. shmget()用于创建或者获取共享内存
    7. shmget()成功返回共享内存的 ID, 失败返回-1
    8. key: 不同的进程使用相同的 key 值可以获取到同一个共享内存
    9. size: 创建共享内存时,指定要申请的共享内存空间大小
    10. shmflg: IPC_CREAT IPC_EXCL
    11. */
    12. int shmget(key_t key, size_t size, int shmflg);
    13.
    13. /*
    14. shmat()将申请的共享内存的物理内存映射到当前进程的虚拟地址空间上
    15. shmat()成功返回返回共享内存的首地址,失败返回 NULL
    16. shmaddr:一般给 NULL,由系统自动选择映射的虚拟地址空间
    17. shmflg: 一般给 0, 可以给 SHM_RDONLY 为只读模式,其他的为读写
    18. */
    19. void* shmat(int shmid, const void *shmaddr, int shmflg);
    20. . /*
    23. shmdt()断开当前进程的 shmaddr 指向的共享内存映射
    24. shmdt()成功返回 0, 失败返回-1
    25. */
    26. int shmdt(const void *shmaddr);
    27.
    28. /*
    29. shmctl()控制共享内存
    30. shmctl()成功返回 0,失败返回-1
    31. cmd: IPC_RMID
    32. */
    33. int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    4.2 代码

    sem.h

      1 #include"sem.h"
      2 static int semid=-1;
      3 void sem_init()
      4 {
      5     semid=semget((key_t)1234,NUM,IPC_CREAT|IPC_EXCL|0600);//全新创建信号量
      6     if(semid==-1)//已存在信号量,所以创建失败
      7     {
      8         semid=semget((key_t)1234,NUM,0600);//成功获取信号量
      9         if(semid==-1)//还是失败,代表创建信号量失败
     10         {
     11             printf("semget err\n");
     12         }
     13     }
     14     else//全新创建成功,进行初始化
     15     {
     16         union semun a;
     17         int arr[NUM]={1,0,0};
     18         for(int i=0;i<NUM;i++)
     19         {
     20             a.val=arr[i];//信号量的初始值
     21             if ( semctl(semid,i,SETVAL,a) == -1 )//信号量设置初始值失败
     22             {
     23                 printf("semctl init err\n");
     24             }
     25         }
     26     }
     27 }
     28 
     29 void sem_p(int index)
     30 {
     31     if(index<0||index>=NUM)
     32     {
     33         return;
     34     }
     35     struct sembuf buf;//定义结构体变量
     36     buf.sem_num = index;//信号量下标(比信号量个数少一个,下标从0开始)
     37     buf.sem_op = -1;//给信号量值-1
     38     buf.sem_flg = SEM_UNDO;//标志位,当信号量没有释放时,系统会对信号量进行销毁释放
     39 
     40     if(semop(semid,&buf,1)==-1)//对信号量操作失败
     41     {
     42         printf("semop p err\n");
     43     }
     44 
     45 }
     46 
     47 void sem_v(int index)
     48 {
     49     if(index<0||index>=NUM)
     50     {
     51         return;
     52     }
     53     struct sembuf buf;
     54     buf.sem_num = index;
     55     buf.sem_op = 1;//v操作
     56     buf.sem_flg = SEM_UNDO;
     57     if(semop(semid,&buf,1)==-1)//对信号量操作失败
     58     {
     59         printf("semop v err\n");
     60     }
     61 }
     62 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    sem.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<sys/sem.h>
      6 
      7 #define SEM1 1
      8 #define SEM2 0
      9 #define SEM3 0
     10 #define NUM  3
     11 
     12 union semun
     13 {
     14     int val;
     15 };
     16 
     17 void sem_init();//初始化
     18 void sem_p(int index);//p操作
     19 void sem_v(int index);//v操作
     20 void sem_destroy();//销毁信号量
    ~                                       
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    main.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<sys/ipc.h>
      6 #include<sys/shm.h>
      7 #include<sys/types.h>
      8 #include"sem.h"
      9 int main()
     10 {
     11     int shmid=shmget((key_t)1234,128,IPC_CREAT|0600);
     12     if(shmid==-1)
     13     {
     14         printf("shmget err\n");
     15         exit(1);
     16     }
     17 
     18     char*s=(char*)shmat(shmid,NULL,0);
     19     if(s==(char*)-1)
     20     {
     21         printf("shmat err\n");
     22         exit(1);
     23     }
     24 
     25     sem_init();
     26     while(1)
     27     {
     28         printf("input \n");
     29         char buff[128]={0};
     30         fgets(buff,128,stdin);
     31         sem_p(SEM1);
     32         strcpy(s,buff);
     33         sem_v(SEM2);
     34         if(strncmp(buff,"end",3)==0)
     35         {
     36             break;
     37         }
     38     }
     39     shmdt(s);//断开映射
     40     //shmctl(shmid,ipcrmid,NULL);移除信号量
     41 }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    test.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<sys/ipc.h>
      6 #include<sys/shm.h>
      7 #include<sys/types.h>
      8 #include"sem.h"
      9 int main()
     10 {
     11     int shmid=shmget((key_t)1234,128,IPC_CREAT|0600);
     12     if(shmid==-1)
     13     {
     14         printf("shmget err\n");
     15         exit(1);
     16     }
     17 
     18     char*s=(char*)shmat(shmid,NULL,0);
     19     if(s==(char*)-1)
     20     {
     21         printf("shmat err\n");
     22         exit(1);
     23     }
     24 
     25     sem_init();
     26     while(1)
     27     {
     28         sem_p(SEM2);
     29         if(strncmp(s,"end",3)==0)
     30         {
     31             break;
     32         }
     33         printf("read:%s\n",s);
     34         sem_v(SEM1);
     35     }
     36     shmdt(s);//断开映射
     		sem_destroy();
     37 }
    ~     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述

    5. 消息队列

    5.1 消息队列

    在这里插入图片描述

    5.2 消息队列函数

    在这里插入图片描述
    消息类型
    在这里插入图片描述

    5.3 消息函数体

    在这里插入图片描述
    ipcs -q 仅显示消息队列

    5.4 添加消息

    在消息队列中添加消息
    在这里插入图片描述


  • 相关阅读:
    DEJA_VU3D - Cesium功能集 之 052-模拟卫星轨道(高空)效果
    nodejs+vue晓海网上订餐系统elementui
    太极限了,JDK的这个BUG都能被我踩到!
    【智能座舱】- 汽车产业的变革,电动化是上半场,而智能化则是下半场
    聚类算法笔记【零基础数模系列】
    ChatGPT自动开发SwiftUI App
    2.1万字,30张图详解操作系统常见面试题(收藏版)
    14届蓝桥青少选拔赛2022年8月21日C++中高级在线考试
    redis最佳实践
    【Docker】Harbor私有仓库与管理
  • 原文地址:https://blog.csdn.net/qq_48580892/article/details/124981115