【Linux】進程通信篇Ⅱ:共享內存、消息隊列、信號量

文章目錄

  • 一、共享內存
    • 1.1 一些接口
      • 1. shmget 函數:申請一個 system v 的共享內存塊
      • 2. ftok 函數:設置唯一標識碼
      • 3. shmctl 函數:控制 system v 的共享內存塊(可以刪除、查看...)
      • 4. shmat 函數:將進程與共享內存塊 關聯\ 掛接(attach)
      • 5. shmdt 函數:將進程與共享內存塊 去關聯(detach)
    • 1.2 一些命令
      • 1. ipcs - - 查看三種 ipc 資源
      • 2. ipcrm -- 刪除某種 ipc 資源
    • 1.3 結論
  • 二、消息隊列
      • 1. msgget 函數:創建消息隊列
      • 2. msgctl 函數
      • 3. msgsnd 和 msgrcv 函數,發送和接收消息
  • 三、信號量
      • 1. semget
      • 2. semctl 函數:可以獲取信號量的相關屬性
      • 3. semop 函數:對信號量進行操作
  • 總結:


一、共享內存

我們知道,進程間通信的本質就是:讓不同的進程,看到同一份資源

這里要介紹的同一份資源就是:內存塊,即 共享內存(shared memory,簡寫為 shm)

共享內存的原理:
1.創建(key 和 共享內存)
2.關聯進程 和 取消關聯
3.釋放共享內存

內存中的每塊共享內存,會有一個 struct shm 結構體,里面放著共享內存的全部屬性,OS 通過這個結構體建立鏈表關系來對所有的共享內存進行管理,就等于把管理 shm 的問題轉化成了管理鏈表的問題。

故:

共享內存
=
共享內存的內核數據結構 (偽代碼:struct shm)
+
真正開辟的內存空間

1.1 一些接口

1. shmget 函數:申請一個 system v 的共享內存塊

頭文件:

#include <sys/ipc.h>
#include <sys/shm.h>// umask的頭文件如下
#include <sys/types.h>
#include <sys/stat.h>

int shmget(key_t key, size_t size, int shmflg);
?
參數 key:

  • 使用 ftok 函數設置的唯一標識碼,他雖由用戶設置,卻是在內核中使用的

?
參數 size

  • 需要申請共享內存塊的大小,單位為字節,不足 PAGE 頁(4KB)時,會向上對齊到 PAGE 頁

?
參數 shmflg:

  • 選項 IPC_CREAT and IPC_EXCL

  • 單獨使用 IPC_CREAT:創建一個共享內存,如果共享內存不存在,就創建,如果已經存在就獲取已經存在的共享內存并返回。

  • IPC_CREAT | IPC_EXCL :IPC_EXCL 必須要配合 IPC_CREAT 使用,創建一個共享內存,如果共享內存不存在,就創建,如果已經存在就出錯返回
    意味著,一起使用時,如果創建成功,對應的shm,一定是最新的!

  • IPC_CREAT | IPC_EXCL | 0666 :上面的基礎上,添加權限(可以配合函數 umask(0) 使用)

?
返回值:

  • 成功會返回一個共享內存標識符,失敗返回 -1

2. ftok 函數:設置唯一標識碼

頭文件

#include <sys/types.h>
#include <sys/ipc.h>

key_t ftok(const char *pathname, int proj_id);
?
參數 pathname

  • 用戶設置的路徑

?
參數 proj_id

  • 用戶設置的項目 id

?
返回值:

  • 根據用戶傳入的參數,結合一定的算法,返回一個沖突概率很低的值。ket_t 就是一個 32 位的整數,是對 int 的封裝

3. shmctl 函數:控制 system v 的共享內存塊(可以刪除、查看…)

頭文件

#include <sys/ipc.h>
#include <sys/shm.h>   

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
?
參數 shmid

  • 需要的共享內存塊的 shmid

?
參數 cmd:

  • 選項 IPC_STAT:把用戶傳入 shmid 的相應內核數據結構信息復制到 buf 中(在調用者有讀權限的情況下,才能成功
  • 選項 IPC_RMID:刪除 shmid 為傳入值的共享內存塊

?
輸出型參數 buf:

  • 需要得到 ipc 信息時傳一個相應類型的值用來接收結果

?
返回值:

  • 失敗返回 -1,成功則根據 cmd 傳入的選項返回對應的值
//The buf argument is a pointer to a shmid_ds structure, defined in <sys/shm.h> as follows:struct shmid_ds {struct ipc_perm shm_perm;    /* Ownership and permissions */size_t          shm_segsz;   /* Size of segment (bytes) */time_t          shm_atime;   /* Last attach time */time_t          shm_dtime;   /* Last detach time */time_t          shm_ctime;   /* Last change time */pid_t           shm_cpid;    /* PID of creator */pid_t           shm_lpid;    /* PID of last shmat(2)/shmdt(2) */shmatt_t        shm_nattch;  /* No. of current attaches */...};//The ipc_perm structure is defined as follows (the highlighted fields  are  settable  using IPC_SET):struct ipc_perm {key_t          __key;    /* Key supplied to shmget(2) */uid_t          uid;      /* Effective UID of owner */gid_t          gid;      /* Effective GID of owner */uid_t          cuid;     /* Effective UID of creator */gid_t          cgid;     /* Effective GID of creator */unsigned short mode;     /* Permissions + SHM_DEST andSHM_LOCKED flags */unsigned short __seq;    /* Sequence number */};

4. shmat 函數:將進程與共享內存塊 關聯\ 掛接(attach)

頭文件

#include <sys/types.h>
#include <sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);
?
參數 shmid

  • 需要的共享內存塊的 shmid

?
參數 shmaddr:

  • 用戶可以選擇虛擬地址作為共享內存塊的起始地址
  • 用戶一般不定義,設為 nullptr 讓 OS 自主定義即可

?
參數 shmflg:

  • 選項 SHM_RDONLY:只讀
  • 0:可以讀寫

?
返回值:

  • 掛接成功,返回共享內存塊的虛擬地址的起始地址

5. shmdt 函數:將進程與共享內存塊 去關聯(detach)

頭文件

#include <sys/types.h>
#include <sys/shm.h>

int shmdt(const void *shmaddr);
?
參數 shmaddr:

  • 共享內存塊的起始地址

?
返回值:

  • 去關聯成功返回 0,失敗返回 -1

1.2 一些命令

1. ipcs - - 查看三種 ipc 資源

ipcs 就是進程間通信(ipc)資源

ipcs:可以查看 消息隊列、共享內存虧塊、信號量
-m:查看 共享內存塊(memory)
-s:查看 信號量(semaphore)

perms:權限
nattach:當前 ipc 掛接的進程數

2. ipcrm – 刪除某種 ipc 資源

ipcrm:刪除一個 消息隊列、共享內存虧塊、信號量
-m:刪除一個共享內存塊,后接 shmid

1.3 結論

  1. 兩個進程管道通信一次,需要進行兩次復制。而共享內存間的通信,可以讓進程們直接在自己映射的地址空間中訪問,減少了拷貝次數()

  2. 管道單方面關閉讀寫端會有相應的保護,而共享內存沒有保護機制(同步互斥)。管道通過系統接口通信,共享內存直接通信

  3. 互斥:任何一個時刻,都只允許一個執行流在進行共享資源的訪問,叫做加鎖

  4. 我們把任何一個時刻,都只允許一個執行流在進行訪問的共享資源,叫做 臨界資源。凡是訪問臨界資源的代碼,叫做臨界區,控制進出臨界區的手段造就了臨界資源。



二、消息隊列

1. msgget 函數:創建消息隊列

頭文件

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg)
?

參數 key:

  • 使用 ftok 函數設置的唯一標識碼

?
參數 msgflg:

  • 選項 IPC_CREAT and IPC_EXCL

  • 單獨使用 IPC_CREAT:創建一個共享內存,如果共享內存不存在,就創建,如果已經存在就獲取已經存在的共享內存并返回。

  • IPC_CREAT | IPC_EXCL :IPC_EXCL 必須要配合 IPC_CREAT 使用,創建一個共享內存,如果共享內存不存在,就創建,如果已經存在就出錯返回
    意味著,一起使用時,如果創建成功,對應的shm,一定是最新的!

  • IPC_CREAT | IPC_EXCL | 0666 :上面的基礎上,添加權限(可以配合函數 umask(0) 使用)

?
返回值:

  • 成功則返回消息隊列的標識符

2. msgctl 函數

頭文件

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
?
參數 msqid

  • 需要的消息隊列的 msqid

?
參數 cmd:

  • 選項 IPC_STAT:把用戶傳入 msqid 的相應內核數據結構信息復制到 buf 中(在調用者有讀權限的情況下,才能成功
  • 選項 IPC_RMID:刪除 msqid 為傳入值的共享內存塊

?
輸出型參數 buf:

  • 需要得到 ipc 信息時傳一個相應類型的值用來接收結果

?
返回值:

  • 成功返回 >= 0 的值,失敗返回 -1
The msqid_ds data structure is defined in <sys/msg.h> as follows:struct msqid_ds {struct ipc_perm msg_perm;     /* Ownership and permissions */time_t          msg_stime;    /* Time of last msgsnd(2) */time_t          msg_rtime;    /* Time of last msgrcv(2) */time_t          msg_ctime;    /* Time of last change */unsigned long   __msg_cbytes; /* Current number of bytes inqueue (nonstandard) */msgqnum_t       msg_qnum;     /* Current number of messagesin queue */msglen_t        msg_qbytes;   /* Maximum number of bytesallowed in queue */pid_t           msg_lspid;    /* PID of last msgsnd(2) */pid_t           msg_lrpid;    /* PID of last msgrcv(2) */};The ipc_perm structure is defined as follows (the highlighted fields  are  settable  using
IPC_SET):struct ipc_perm {key_t          __key;       /* Key supplied to msgget(2) */uid_t          uid;         /* Effective UID of owner */gid_t          gid;         /* Effective GID of owner */uid_t          cuid;        /* Effective UID of creator */gid_t          cgid;        /* Effective GID of creator */unsigned short mode;        /* Permissions */unsigned short __seq;       /* Sequence number */};

3. msgsnd 和 msgrcv 函數,發送和接收消息

頭文件

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
?
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
?

參數 msqid:

  • 發送和接收訪問的同一個消息隊列
    ?

參數 msgp:

  • 發送或接收的數據塊
    ?

參數 msgsz:

  • 發送或接收數據塊的大小
    ?

參數 msgflg:

  • 選項,一般填 0 即可
    ?

參數 msgtyp:

  • msgbuf 里面的 mtype
// The msgp argument is a pointer to caller-defined structure of the following general form:struct msgbuf {long mtype;       /* message type, must be > 0 */char mtext[1];    /* message data */
};


三、信號量

信號量 / 信號燈(semaphore),本質 就是一個計數器,是一個描述資源數量的計數器

舉個例子:

  • 比如我們任何一個執行流,像訪問臨界資源中的一個子資源的時候,不能直接訪問,需要 先申請信號量資源(P操作),此時 count-- 。只要申請信號量成功,未來就一定能拿到一個子資源。(類似搖號)

  • 然后進入進程自己的臨界區,訪問對應的臨界資源。

  • 使用完成后,進程釋放信號量資源(V操作),只要將計數器增加 count++,就表示將我們對應的資源進行了歸還。

至此,進程通過執行代碼來申請,意味著,所有進程都得先看到信號量,信號量就是一個共享資源。(信號量保護共享資源,自己卻又是一個共享資源)

故,信號量必須保證自己的 ++ - - 是原子的
也,信號量被歸類到了進程間通信

信號量部分未完待續~

1. semget

頭文件

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semget(key_t key, int nsems, int semflg);
?
參數 key:

  • 使用 ftok 函數設置的唯一標識碼,他雖由用戶設置,卻是在內核中使用的

?
參數 nsems:

  • 申請信號量的個數(叫做信號量集)

?
參數 semflg:

  • 選項 IPC_CREAT and IPC_EXCL

  • 單獨使用 IPC_CREAT:創建一個共享內存,如果共享內存不存在,就創建,如果已經存在就獲取已經存在的共享內存并返回。

  • IPC_CREAT | IPC_EXCL :IPC_EXCL 必須要配合 IPC_CREAT 使用,創建一個共享內存,如果共享內存不存在,就創建,如果已經存在就出錯返回
    意味著,一起使用時,如果創建成功,對應的shm,一定是最新的!

  • IPC_CREAT | IPC_EXCL | 0666 :上面的基礎上,添加權限(可以配合函數 umask(0) 使用)

?
返回值:

  • 成功會返回一個信號量計數器標識符,失敗返回 -1

2. semctl 函數:可以獲取信號量的相關屬性

頭文件

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semctl(int semid, int semnum, int cmd, ...);
?
參數 semid:

  • 需要的信號量的semid

?
參數 semnum:

  • 信號量編號

?
參數 cmd:

  • 選項 IPC_STAT:把用戶傳入 msqid 的相應內核數據結構信息復制到 buf 中(在調用者有讀權限的情況下,才能成功
  • 選項 IPC_RMID:刪除 msqid 為傳入值的共享內存塊

?
返回值:

  • 成功返回 >= 0 的值,失敗返回 -1
//This  function  has  three  or four arguments, depending on cmd.  When there are four, the
//fourth has the type union semun.  The calling program must define this union as follows:union semun {int              val;    /* Value for SETVAL */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */};//The semid_ds data structure is defined in <sys/sem.h> as follows:struct semid_ds {struct ipc_perm sem_perm;  /* Ownership and permissions */time_t          sem_otime; /* Last semop time */time_t          sem_ctime; /* Last change time */unsigned long   sem_nsems; /* No. of semaphores in set */};//The ipc_perm structure is defined as follows (the highlighted fields  are  settable  usingIPC_SET):struct ipc_perm {key_t          __key; /* Key supplied to semget(2) */uid_t          uid;   /* Effective UID of owner */gid_t          gid;   /* Effective GID of owner */uid_t          cuid;  /* Effective UID of creator */gid_t          cgid;  /* Effective GID of creator */unsigned short mode;  /* Permissions */unsigned short __seq; /* Sequence number */};

3. semop 函數:對信號量進行操作

頭文件

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semop(int semid, struct sembuf *sops, unsigned nsops);
?
參數 sops:

  • 需要用戶自己定義后傳入,設置結構體內容,以此達到對信號量的 PV 操作等等
//Each semaphore in a System V semaphore set has the following associated values:unsigned short  semval;   /* semaphore value */unsigned short  semzcnt;  /* # waiting for zero */unsigned short  semncnt;  /* # waiting for increase */pid_t           sempid;   /* ID of process that did last op *///semop() performs operations on selected semaphores in the set indicated by semid.  
//Each of the nsops elements in the array pointed to by sops specifies an operation to be  performed on a single semaphore.  
//The elements of this structure are of type struct sembuf, containing the following members:unsigned short sem_num;  /* semaphore number */short          sem_op;   /* semaphore operation */short          sem_flg;  /* operation flags */

總結:

共享內存、消息隊列、信號量 這三種 ipc 都有各自的內核數據結構體,而結構體的第一個成員都是 struct ipc_perm xx_perm

可以理解為 OS 將這三種 ipc 都放進了一個 struct ipc_perm* ipc_id_arr[] 指針數組中進行管理(這里只是做理解解釋,實際上更復雜)。

OS 通過指針,可以找到每個結構體(同時也是每個結構的第一個成員,即 struct ipc_perm xx_perm),在其中找到 key 值就可以確定。

要訪問里面的內容時,以共享內存舉例

((struct shmid_ds*)ipc_id_arr[n])->other...

對指針進行強轉,就可以訪問到其中內容了,這也是一種多態。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39666.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39666.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39666.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一種多策略下RabbitMQ的延時隊列實現

1.為什么會用到延時隊列? 場景: 最近在開發一款系統中遇到這樣一個場景,A系統開通套餐需要把套餐信息以郵件的形式發送給相關工作人員,經過人工審核通過后,在B系統里面開通,A系統會調B系統套餐列表接口查詢套餐是否開通成功,開通成功則從A系統去完成訂單,假如超過設定時間未開…

韋東山-電子量產工具項目:顯示單元

所有代碼都已通過測試跑通&#xff0c;其中代碼結構如下&#xff1a; 一、include文件夾 1.1 disp_manager.h #ifndef _DISP_MANAGER_H //防止頭文件重復包含,只要右邊的出現過&#xff0c;就不會再往下編譯 #define _DISP_MANAGER_H //區域結構體 typedef struct DispBuff …

[element-ui] el-table表格合并 span-method

用rowIndex, columnIndex 找到要合并的開始單元格 return {rowspan: 1,colspan: 1 } 表示表格不變 return {rowspan: 2,colspan: 1 } 表示表格向下合并一個單元格 return {rowspan: 1,colspan: 2 } 表示表格向右合并一個單元格 return {rowspan: 0,colspan: 0 } 表示刪除此單元…

leetcode810. 黑板異或游戲(博弈論 - java)

黑板異或游戲 lc 810 - 黑板異或游戲題目描述博弈論 動態規劃 lc 810 - 黑板異或游戲 難度 - 困難 原題鏈接 - 黑板異或游戲 題目描述 黑板上寫著一個非負整數數組 nums[i] 。 Alice 和 Bob 輪流從黑板上擦掉一個數字&#xff0c;Alice 先手。如果擦除一個數字后&#xff0c;剩…

談談網絡協議的定義、組成和重要性

個人主頁&#xff1a;insist--個人主頁?????? 本文專欄&#xff1a;網絡基礎——帶你走進網絡世界 本專欄會持續更新網絡基礎知識&#xff0c;希望大家多多支持&#xff0c;讓我們一起探索這個神奇而廣闊的網絡世界。 目錄 一、網絡協議的定義 二、網絡協議的組成 1、…

出于網絡安全考慮,印度啟用本土操作系統”瑪雅“取代Windows

據《印度教徒報》報道&#xff0c;印度將放棄微軟系統&#xff0c;選擇新的操作系統和端點檢測與保護系統。 備受期待的 "瑪雅操作系統 "將很快用于印度國防部的數字領域&#xff0c;而新的端點檢測和保護系統 "Chakravyuh "也將一起面世。 不過&#xf…

C++--類型轉換

1.什么是類型轉換 在傳統C語言中&#xff0c;由強制類型轉換和隱式類型轉換&#xff0c;隱式類型轉換&#xff0c;編譯器在在編譯階段自動處理&#xff0c;能轉換則轉換&#xff0c;強制類型轉換由用戶自己轉換。 缺陷&#xff1a; 轉換的可視性比較差&#xff0c;所有的轉換形…

Go語言中關鍵字type的多重應用場景詳解

當談及Go語言中的關鍵字type時&#xff0c;我們通常會想到用于定義結構體和接口的常見用法。然而&#xff0c;"type"關鍵字實際上有許多其他用法&#xff0c;本文將對其中幾種常見用法進行簡要總結記錄。 定義結構體和方法 在Go中&#xff0c;我們可以使用type來定…

運維監控學習筆記5

Linux的內存是虛擬內存&#xff0c;是物理內存和交換分區swap。 內存&#xff1a; 頁&#xff1a;4K&#xff0c; 硬盤&#xff1a;塊。 尋址&#xff1a; 空間&#xff1a;內存的合并。大頁內存。 free命令&#xff1a; [rootvm1 ~]# free -htotal used fre…

javap獲取Kotlin方法JNI方法簽名

獲取Kotlin方法簽名和JAVA不一樣的地方就是需要使用Kotlin 命令行編譯器生成.class文件&#xff1a; 編寫一個Kotlin類&#xff0c;添加JNI方法&#xff1a; class TestLib {external fun init(callBack: CallBack)interface CallBack{fun onData(count:Int,data:String)} }在…

cesium學習記錄08-鼠標繪制多邊形

上一篇學習了實體的一些基礎知識&#xff0c;這一篇來學習鼠標繪制實體多邊形的實現 一、方法一&#xff1a; 1&#xff0c;結果顯示 貼地&#xff1a; 不貼地&#xff1a; 2&#xff0c;方法全部代碼&#xff1a; 主方法&#xff1a; /*** 繪制多邊形* param {Object} op…

華為OD機試 - 公共子串計算(Java 2023 B卷 100分)

目錄 專欄導讀一、題目描述二、輸入描述三、輸出描述四、解題思路五、Java算法源碼六、效果展示 華為OD機試 2023B卷題庫瘋狂收錄中&#xff0c;刷題點這里 專欄導讀 本專欄收錄于《華為OD機試&#xff08;JAVA&#xff09;真題&#xff08;A卷B卷&#xff09;》。 刷的越多&…

VictoriaMetrics部署及vmalert集成釘釘告警

1、部署VictoriaMetrics cd /usr/local wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.65.0/victoria-metrics-amd64-v1.65.0.tar.gz mkdir victoria-metrics && tar -xvzf victoria-metrics-amd64-v1.65.0.tar.gz && \ mv …

論AI GPT跨境貿易架構及其應用

摘要 2023年初,我司啟動了智慧化跨境貿易供應鏈一體化平臺的建設工作。我在該項目中擔任系統架構設計師的職務,主要負責設計平臺系統架構和安全體系架構。該平臺以移動信息化發展為契機,采用”平臺+AI”的模式解決現有應用的集中移動化需求。平臺整體的邏輯復雜,對系統的高…

react之Hooks的介紹、useState與useEffect副作用的使用

react之Hooks的介紹、useState與useEffect副作用的使用 一、Hooks的基本介紹二、useState的使用2.1 簡單使用2.2 數組結構簡化2.3 狀態的讀取和修改2.3 組件的更新過程 三、useEffect的使用3.1 副作用介紹3.2 基本使用3.3 依賴3.4 不要對依賴項撒謊3.5 依賴項可以是空數組3.6 清…

ZZULIOJ 1193: 單科成績排序(結構體專題),Java

ZZULIOJ 1193: 單科成績排序&#xff08;結構體專題&#xff09;&#xff0c;Java 題目描述 有一學生成績表&#xff0c;包括學號、姓名、3門課程成績。請按要求排序輸出&#xff1a;若輸入1&#xff0c;則按第1門課成績降序輸出成績表&#xff0c;若輸入為i&#xff08;1<…

清風數學建模——擬合算法

擬合算法 文章目錄 擬合算法概念 確定擬合曲線最小二乘法的幾何解釋求解最小二乘法matlab求解最小二乘法如何評價擬合的好壞計算擬合優度的代碼 概念 在前面的篇幅中提到可以使用插值算法&#xff0c;通過給定的樣本點推算出一定的曲線從而推算出一些想要的值。但存在一些問題…

解決內網GitLab 社區版 15.11.13項目拉取失敗

問題描述 GitLab 社區版 發布不久&#xff0c;搭建在內網拉取項目報錯&#xff0c;可能提示 unable to access https://github.comxxxxxxxxxxx: Failed to connect to xxxxxxxxxxxxxGit clone error - Invalid argument error:14077438:SSL routines:SSL23_GET_S 15.11.13ht…

QT網絡編程之TCP

QT網絡編程之TCP TCP 編程需要用到倆個類: QTcpServer 和 QTcpSocket。 #------------------------------------------------- # # Project created by QtCreator 2023-08-

mysql截取最后一個字符之前的數據

1、mysql截取最后一個字符之前的數據 select --截取斜杠之前的數據REVERSE(SUBSTR(REVERSE(SPNH-dfg-2012) ; --截取斜杠后的數據 INSTR(REVERSE(SPNH-fg-2012),-)1))2、mysql獲取最后一個字符后的數據 select SUBSTRING_INDEX(SPNH-dfg-2012,-,-1) 3、mysql更新某個字段…