clock_nanosleep系統調用及示例

41. clock_nanosleep - 高精度睡眠

函數介紹

clock_nanosleep系統調用提供納秒級精度的睡眠功能,支持絕對時間和相對時間兩種模式,比傳統的nanosleep更加靈活。

函數原型

#include <time.h>int clock_nanosleep(clockid_t clock_id, int flags,const struct timespec *request,struct timespec *remain);

功能

使進程睡眠指定的時間,支持高精度納秒級睡眠。

參數

  • clockid_t clock_id: 時鐘ID
  • int flags: 標志位
    • 0: 相對時間睡眠
    • TIMER_ABSTIME: 絕對時間睡眠
  • const struct timespec *request: 請求睡眠的時間
  • struct timespec *remain: 剩余時間(被信號中斷時)

返回值

  • 成功時返回0
  • 被信號中斷時返回-1,并設置errno為EINTR
  • 失敗時返回-1,并設置其他errno

相似函數

  • nanosleep(): 納秒級睡眠
  • sleep(): 秒級睡眠
  • usleep(): 微秒級睡眠

示例代碼

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>// 信號處理函數
void signal_handler(int sig) {printf("  接收到信號 %d\n", sig);
}int main() {struct timespec request, remain, start, end;int result;printf("=== Clock_nanosleep 函數示例 ===\n");// 示例1: 相對時間睡眠printf("\n示例1: 相對時間睡眠\n");// 睡眠100毫秒request.tv_sec = 0;request.tv_nsec = 100000000; // 100毫秒 = 100,000,000納秒if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) {perror("  獲取開始時間失敗");}printf("  開始睡眠: %ld.%09ld 秒\n", start.tv_sec, start.tv_nsec);result = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, NULL);if (result == -1) {if (errno == EINTR) {printf("  睡眠被信號中斷\n");} else {printf("  睡眠失敗: %s\n", strerror(errno));}} else {printf("  睡眠完成\n");if (clock_gettime(CLOCK_MONOTONIC, &end) == -1) {perror("  獲取結束時間失敗");} else {long long actual_sleep = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);printf("  實際睡眠時間: %lld 納秒\n", actual_sleep);}}// 示例2: 絕對時間睡眠printf("\n示例2: 絕對時間睡眠\n");// 獲取當前時間if (clock_gettime(CLOCK_REALTIME, &start) == 0) {printf("  當前時間: %ld.%09ld 秒\n", start.tv_sec, start.tv_nsec);// 設置絕對睡眠時間(當前時間+2秒)struct timespec absolute_time;absolute_time.tv_sec = start.tv_sec + 2;absolute_time.tv_nsec = start.tv_nsec;printf("  絕對睡眠時間: %ld.%09ld 秒\n", absolute_time.tv_sec, absolute_time.tv_nsec);result = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &absolute_time, NULL);if (result == -1) {if (errno == EINTR) {printf("  絕對時間睡眠被信號中斷\n");} else {printf("  絕對時間睡眠失敗: %s\n", strerror(errno));}} else {printf("  絕對時間睡眠完成\n");}}// 示例3: 被信號中斷的睡眠printf("\n示例3: 被信號中斷的睡眠\n");// 設置信號處理signal(SIGUSR1, signal_handler);// 啟動另一個線程發送信號pid_t pid = fork();if (pid == 0) {// 子進程:延遲發送信號sleep(1);kill(getppid(), SIGUSR1);exit(0);} else if (pid > 0) {// 父進程:長時間睡眠request.tv_sec = 5;request.tv_nsec = 0;printf("  開始5秒睡眠,1秒后會被信號中斷\n");result = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, &remain);if (result == -1 && errno == EINTR) {printf("  睡眠被信號中斷\n");printf("  剩余時間: %ld.%09ld 秒\n", remain.tv_sec, remain.tv_nsec);}wait(NULL); // 等待子進程結束}// 示例4: 錯誤處理演示printf("\n示例4: 錯誤處理演示\n");// 使用無效的時鐘IDrequest.tv_sec = 1;request.tv_nsec = 0;result = clock_nanosleep(999, 0, &request, NULL);if (result == -1) {if (errno == EINVAL) {printf("  無效時鐘ID錯誤處理正確: %s\n", strerror(errno));}}// 使用無效的時間值request.tv_sec = -1;request.tv_nsec = 0;result = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, NULL);if (result == -1) {if (errno == EINVAL) {printf("  無效時間值錯誤處理正確: %s\n", strerror(errno));}}// 使用過大的納秒值request.tv_sec = 0;request.tv_nsec = 1000000000; // 10億納秒 = 1秒,但應該 < 1秒result = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, NULL);if (result == -1) {if (errno == EINVAL) {printf("  納秒值過大錯誤處理正確: %s\n", strerror(errno));}}// 示例5: 不同時鐘的睡眠效果printf("\n示例5: 不同時鐘的睡眠效果\n");printf("CLOCK_REALTIME睡眠:\n");printf("  - 基于系統實時時間\n");printf("  - 受系統時間調整影響\n");printf("  - 適用于絕對時間睡眠\n\n");printf("CLOCK_MONOTONIC睡眠:\n");printf("  - 基于單調遞增時間\n");printf("  - 不受系統時間調整影響\n");printf("  - 適用于相對時間睡眠\n\n");// 示例6: 高精度定時器演示printf("示例6: 高精度定時器演示\n");printf("創建100毫秒間隔的定時器循環:\n");struct timespec interval;interval.tv_sec = 0;interval.tv_nsec = 100000000; // 100毫秒for (int i = 0; i < 5; i++) {if (clock_gettime(CLOCK_MONOTONIC, &start) == 0) {printf("  第%d次: 時間 %ld.%09ld\n", i+1, start.tv_sec, start.tv_nsec);}result = clock_nanosleep(CLOCK_MONOTONIC, 0, &interval, NULL);if (result == -1) {if (errno == EINTR) {printf("  第%d次: 睡眠被中斷\n", i+1);break;}}}// 示例7: 睡眠精度測試printf("\n示例7: 睡眠精度測試\n");struct timespec sleep_times[] = {{0, 1000},      // 1微秒{0, 10000},     // 10微秒{0, 100000},    // 100微秒{0, 1000000},   // 1毫秒{0, 10000000},  // 10毫秒{0, 100000000}, // 100毫秒{1, 0}          // 1秒};const char *time_labels[] = {"1微秒", "10微秒", "100微秒", "1毫秒", "10毫秒", "100毫秒", "1秒"};printf("睡眠精度測試結果:\n");for (int i = 0; i < 7; i++) {if (clock_gettime(CLOCK_MONOTONIC, &start) == 0) {result = clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep_times[i], NULL);if (clock_gettime(CLOCK_MONOTONIC, &end) == 0) {long long actual = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);long long requested = sleep_times[i].tv_sec * 1000000000LL + sleep_times[i].tv_nsec;long long diff = actual - requested;printf("  %-8s: 請求%8lld ns, 實際%8lld ns, 誤差%+6lld ns\n",time_labels[i], requested, actual, diff);}}}// 示例8: 實際應用場景printf("\n示例8: 實際應用場景\n");// 場景1: 實時系統定時printf("場景1: 實時系統定時\n");printf("在實時應用中確保精確的時間間隔\n");// 場景2: 性能基準測試printf("\n場景2: 性能基準測試\n");printf("提供精確的延遲控制用于性能測試\n");// 場景3: 動畫和游戲循環printf("\n場景3: 動畫和游戲循環\n");printf("維持穩定的幀率和更新頻率\n");// 場景4: 網絡超時控制printf("\n場景4: 網絡超時控制\n");printf("實現精確的網絡操作超時機制\n");printf("\n總結:\n");printf("clock_nanosleep提供納秒級精度的睡眠功能\n");printf("支持相對時間和絕對時間兩種模式\n");printf("比傳統sleep函數更加靈活和精確\n");printf("正確處理信號中斷和剩余時間計算\n");printf("適用于需要高精度時間控制的應用場景\n");return 0;
}

42. clock_settime - 設置時鐘時間

函數介紹

clock_settime系統調用用于設置指定時鐘的時間值。它允許程序修改系統時鐘,主要用于時間同步和系統管理。

函數原型

#include <time.h>int clock_settime(clockid_t clk_id, const struct timespec *tp);

功能

設置指定時鐘的時間值。

參數

  • clockid_t clk_id: 時鐘ID(通常為CLOCK_REALTIME)
  • const struct timespec *tp: 指向timespec結構體的指針,包含新的時間值

返回值

  • 成功時返回0
  • 失敗時返回-1,并設置errno

特殊限制

  • 需要CAP_SYS_TIME能力或root權限
  • 通常只能設置CLOCK_REALTIME時鐘

相似函數

  • settimeofday(): 設置系統時間
  • stime(): 設置系統時間(已廢棄)

示例代碼

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>int main() {struct timespec current_time, new_time;int result;printf("=== Clock_settime 函數示例 ===\n");printf("當前用戶 UID: %d\n", getuid());printf("當前有效 UID: %d\n", geteuid());// 示例1: 獲取當前時間printf("\n示例1: 獲取當前時間\n");if (clock_gettime(CLOCK_REALTIME, &current_time) == -1) {perror("  獲取當前時間失敗");} else {printf("  當前系統時間: %ld.%09ld 秒\n", current_time.tv_sec, current_time.tv_nsec);printf("  對應日期: %s", ctime(&current_time.tv_sec));}// 示例2: 權限檢查printf("\n示例2: 權限檢查\n");// 嘗試設置時間(通常會失敗)new_time.tv_sec = current_time.tv_sec;new_time.tv_nsec = current_time.tv_nsec;result = clock_settime(CLOCK_REALTIME, &new_time);if (result == -1) {if (errno == EPERM) {printf("  權限不足設置時間: %s\n", strerror(errno));printf("  說明: 需要CAP_SYS_TIME能力或root權限\n");} else {printf("  設置時間失敗: %s\n", strerror(errno));}} else {printf("  時間設置成功\n");}// 示例3: 錯誤處理演示printf("\n示例3: 錯誤處理演示\n");// 使用無效的時鐘IDresult = clock_settime(999, &new_time);if (result == -1) {if (errno == EINVAL) {printf("  無效時鐘ID錯誤處理正確: %s\n", strerror(errno));}}// 使用無效的時間值struct timespec invalid_time;invalid_time.tv_sec = -1;invalid_time.tv_nsec = 0;result = clock_settime(CLOCK_REALTIME, &invalid_time);if (result == -1) {if (errno == EINVAL) {printf("  無效時間值錯誤處理正確: %s\n", strerror(errno));}}// 使用過大的納秒值invalid_time.tv_sec = current_time.tv_sec;invalid_time.tv_nsec = 1000000000; // 10億納秒,應該 < 1秒result = clock_settime(CLOCK_REALTIME, &invalid_time);if (result == -1) {if (errno == EINVAL) {printf("  納秒值過大錯誤處理正確: %s\n", strerror(errno));}}// 使用NULL指針result = clock_settime(CLOCK_REALTIME, NULL);if (result == -1) {if (errno == EFAULT) {printf("  NULL指針錯誤處理正確: %s\n", strerror(errno));}}// 示例4: 支持的時鐘類型printf("\n示例4: 支持的時鐘類型\n");printf("CLOCK_REALTIME:\n");printf("  - 系統實時鐘\n");printf("  - 可以被設置\n");printf("  - 用于表示當前時間\n\n");printf("其他時鐘類型:\n");printf("  - CLOCK_MONOTONIC: 通常不能設置\n");printf("  - CLOCK_PROCESS_CPUTIME_ID: 不能設置\n");printf("  - CLOCK_THREAD_CPUTIME_ID: 不能設置\n\n");// 示例5: 時間格式轉換printf("示例5: 時間格式轉換\n");if (clock_gettime(CLOCK_REALTIME, &current_time) == 0) {printf("  當前時間: %ld.%09ld 秒\n", current_time.tv_sec, current_time.tv_nsec);// 從日期字符串轉換為time_tstruct tm time_info;strptime("2024-01-01 12:00:00", "%Y-%m-%d %H:%M:%S", &time_info);time_t new_time_t = mktime(&time_info);printf("  轉換時間: %s", ctime(&new_time_t));// 轉換為timespec格式struct timespec converted_time;converted_time.tv_sec = new_time_t;converted_time.tv_nsec = 0;printf("  timespec格式: %ld.%09ld 秒\n", converted_time.tv_sec, converted_time.tv_nsec);}// 示例6: 時區考慮printf("\n示例6: 時區考慮\n");if (clock_gettime(CLOCK_REALTIME, &current_time) == 0) {printf("  UTC時間: %ld.%09ld 秒\n", current_time.tv_sec, current_time.tv_nsec);// 獲取本地時區偏移struct tm *utc_tm = gmtime(&current_time.tv_sec);struct tm *local_tm = localtime(&current_time.tv_sec);time_t utc_time = mktime(utc_tm);time_t local_time = mktime(local_tm);long tz_offset = local_time - utc_time;printf("  時區偏移: %+ld 秒\n", tz_offset);}// 示例7: 安全考慮printf("\n示例7: 安全考慮\n");printf("使用clock_settime的安全注意事項:\n");printf("1. 需要適當的權限(CAP_SYS_TIME或root)\n");printf("2. 不當的時間設置可能影響系統穩定性\n");printf("3. 時間跳躍可能影響依賴時間的應用程序\n");printf("4. 應該使用NTP等標準時間同步服務\n");printf("5. 在生產環境中謹慎使用\n\n");// 示例8: 實際應用場景printf("示例8: 實際應用場景\n");// 場景1: NTP客戶端printf("場景1: NTP客戶端\n");printf("  - 從NTP服務器獲取時間\n");printf("  - 調整系統時鐘\n");printf("  - 保持時間同步\n\n");// 場景2: 系統初始化printf("場景2: 系統初始化\n");printf("  - 設置初始系統時間\n");printf("  - 從硬件時鐘同步\n");printf("  - 恢復時間設置\n\n");// 場景3: 調試和測試printf("場景3: 調試和測試\n");printf("  - 設置特定時間進行測試\n");printf("  - 模擬時間相關場景\n");printf("  - 性能基準測試\n\n");// 場景4: 時間同步服務printf("場景4: 時間同步服務\n");printf("  - 分布式系統時間協調\n");printf("  - 數據庫事務時間戳\n");printf("  - 日志時間同步\n\n");// 示例9: 替代方案printf("示例9: 替代方案\n");printf("現代時間管理推薦使用:\n");printf("1. NTP守護進程(ntpd)\n");printf("2. systemd-timesyncd\n");printf("3. chrony\n");printf("4. chronyd\n");printf("5. 避免手動設置系統時間\n\n");printf("總結:\n");printf("clock_settime用于設置系統時鐘時間\n");printf("需要適當的權限才能使用\n");printf("主要用于時間同步服務\n");printf("不當使用可能影響系統穩定性\n");printf("推薦使用標準的時間同步服務\n");return 0;
}

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

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

相關文章

用了Flutter包體積增大就棄用Flutter嗎?包體積與開發效率,這兩者之間如何權衡?

是否因包體積增大而棄用 Flutter&#xff0c;本質上是 “短期成本&#xff08;包體積&#xff09;” 與 “長期價值&#xff08;跨平臺效率、體驗一致性等&#xff09;” 的權衡 。這一決策沒有絕對答案&#xff0c;需結合項目階段、用戶群體、業務需求等具體場景分析。以下從核…

80道面試經典題目

1.OSI參考模型七層網絡協議? 物理層:定義計算機、網絡設備、以及直接連接的介質、接口類型的標準,建立比特流的傳輸,用來組件物理網絡的連接。 數據鏈路層:建立邏輯連接、進行硬件地址尋址,差錯校驗、差錯恢復等功能。 網絡層:進行邏輯地址尋址,實現不同網絡之間的通…

本周大模型新動向:KV緩存壓縮、低成本高性能推理框架、多智能體協作

點擊藍字關注我們AI TIME歡迎每一位AI愛好者的加入&#xff01;01Compress Any Segment Anything Model (SAM)受SAM在零樣本分割任務上卓越表現的驅動&#xff0c;其各類變體已被廣泛應用于醫療、智能制造等場景。然而&#xff0c;SAM系列模型體量巨大&#xff0c;嚴重限制了在…

利用frp實現內網穿透功能(服務器)Linux、(內網)Windows

適用于&#xff1a; 本地電腦&#xff08;windows&#xff09;或者Linux(本篇未介紹&#xff09; 工具&#xff1a;FRP&#xff08;fast reverse proxy&#xff09; 系統&#xff1a;Linux、Windows 架構&#xff1a;x86、amd Frp版本&#xff1a;frp_0.62.1_windows_amd64準備…

結合二八定律安排整塊時間

你是不是常常感覺一天到晚忙忙碌碌&#xff0c;卻總覺得沒干成幾件“要緊事”&#xff1f;時間仿佛從指縫間溜走&#xff0c;成就感卻遲遲不來&#xff1f;其實&#xff0c;高效能人士的秘訣往往藏在最簡單的原則里。今天&#xff0c;我們就來聊聊如何巧妙運用“二八定律”&…

波形發生器AWG硬件設計方案

目錄 簡介 設計需求 設計方案 核心原理圖展示 簡介 波形發生器是一種數據信號發生器&#xff0c;在調試硬件時&#xff0c;常常需要加入一些信號&#xff0c;以觀察電路工作是否正常。用一般的信號發生器&#xff0c;不但笨重&#xff0c;而且只發一些簡單的波形&#xff…

11.Dockerfile簡介

1.是什么&#xff1f; dockerfile是用來構建鏡像的文本文件&#xff0c;是由一條條構建鏡像所需的指令和參數構成的腳本。 構建三步驟 編寫dockerfile文件docker build命令構建鏡像docker run依鏡像運行的容器實列 2.dockerfile構建過程解析 1)dockerfile內容的基礎知識 …

C# 接口(interface 定義接口的關鍵字)

目錄 使用接口案例 接口繼承 練習 定義一個接口&#xff0c;在語法中與定義一個抽象類是沒有區別的&#xff0c;但是不允許提供接口中任意成員的實現方式&#xff0c;一般接口只會包含方法 、索引器和事件的聲明&#xff0c; 不允許聲明成員的修飾符&#xff0c; public都不…

5190 - 提高:DFS序和歐拉序:樹上操作(區域修改1)

題目傳送門 時間限制 : 2 秒 內存限制 : 256 MB 有一棵點數為 N 的樹&#xff0c;以點 1 為根&#xff0c;且樹點有邊權。然后有 M 個 操作&#xff0c;分為三種&#xff1a; 操作 1 &#xff1a;把某個節點 x 的點權增加 a 。 操作 2 &#xff1a;把某個節點 x 為根的子樹中…

【Oracle】數據泵

ORACLE數據庫 數據泵 核心參數全解析 ORACLE expdp 命令使用詳解 1.ATTACH[schema_name.]job_name Schema_name 用于指定方案名,job_name 用于指定導出作業名.注意,如果使用 ATTACH 選項,在命令行除了連接字符串和 ATTACH 選項外,不能指定任何其他選項,示例如下: expdp hr/hr A…

機器學習的算法有哪些?

&#x1f31f; 歡迎來到AI奇妙世界&#xff01; &#x1f31f; 親愛的開發者朋友們&#xff0c;大家好&#xff01;&#x1f44b; 我是人工智能領域的探索者與分享者&#xff0c;很高興在CSDN與你們相遇&#xff01;&#x1f389; 在這里&#xff0c;我將持續輸出AI前沿技術、實…

【計算機網絡】OSI七層模型

OSI七層模型為什么需要OSI七層模型&#xff1f;OSI七層模型具體是什么&#xff1f;Layer7&#xff1a;應用層&#xff08;Application Layer&#xff09;Layer6&#xff1a;表示層&#xff08;Presentation Layer&#xff09;Layer5&#xff1a;會話層&#xff08;Session Laye…

RS485轉Profinet網關配置指南:高效啟動JRT激光測距傳感器測量模式

RS485轉Profinet網關配置指南&#xff1a;高效啟動JRT激光測距傳感器測量模式RS485轉Profinet網關&#xff1a;讓JRT激光測距傳感器高效開啟測量模式在工業自動化場景中&#xff0c;設備間的高效通信是實現精準控制的關鍵。RS485轉Profinet網關作為連接傳統RS485設備與現代Prof…

「日拱一碼」040 機器學習-不同模型可解釋方法

目錄 K最近鄰(KNN) - 基于距離的模型 決策邊界可視化 查看特定樣本的最近鄰 ?隨機森林(RF) - 樹模型 feature_importances_ SHAP值分析 可視化單棵樹 多層感知器(MLP) - 神經網絡 部分依賴圖 LIME解釋器 權重可視化 支持向量回歸(SVR) - 核方法 支持向量可視化 部…

編程與數學 03-002 計算機網絡 09_傳輸層功能

編程與數學 03-002 計算機網絡 09_傳輸層功能一、傳輸層的作用&#xff08;一&#xff09;進程間通信&#xff08;二&#xff09;提供可靠傳輸&#xff08;三&#xff09;復用與分用二、TCP協議&#xff08;一&#xff09;TCP的連接建立與釋放&#xff08;二&#xff09;TCP的可…

14. Web服務器-Nginx-工作原理

文章目錄前言一、簡介二、工作原理1. 多進程架構2. 事件驅動模型3. 模塊化設計三、工作流程1. 啟動階段2. 等待連接3. 請求處理階段4. 響應構造與輸出5. 連接關閉前言 Nginx? Nginx&#xff08;發音為“Engine-X”&#xff09;是一款高性能的開源Web服務器軟件&#xff0c;同…

AP-0316:集 USB 即插即用、智能降噪于一體的多功能 AI 聲卡,重新定義清晰語音交互

AP-0316突發噪音和抗風噪測試還在為語音設備的噪音刺耳、連接復雜、功放適配麻煩而頭疼&#xff1f;AP-0316 多功能 AI 降噪消回音 USB 聲卡來了 —— 以 “USB 即插即用 自帶功放 智能降噪 場景適配” 四大核心優勢&#xff0c;將專業級語音處理技術變得簡單易用&#xff0…

Baumer工業相機堡盟工業相機如何通過YoloV8深度學習模型實現衛星圖像識別(C#代碼,UI界面版)

Baumer工業相機堡盟工業相機如何通過YoloV8深度學習模型實現衛星圖像識別&#xff08;C#代碼&#xff0c;UI界面版&#xff09;工業相機使用YoloV8模型實現水下魚類識別工業相機通過YoloV8模型實現衛星圖像識別的技術背景在相機SDK中獲取圖像轉換圖像的代碼分析工業相機圖像轉換…

某d的評論爬蟲學習

本教程僅用于技術研究&#xff0c;請確保遵守目標網站的服務條款。實際使用前應獲得官方授權&#xff0c;避免高頻請求影響服務器&#xff0c;否則可能承擔法律責任。此腳本僅攔截公開評論接口&#xff0c;不涉及用戶私密數據。請勿修改代碼監聽其他請求。分享一下爬某抖評論的…

SQLite 注入:理解與防御

SQLite 注入&#xff1a;理解與防御 引言 隨著互聯網技術的飛速發展&#xff0c;數據庫已成為各類應用程序的核心組成部分。SQLite 作為一款輕量級的關系型數據庫&#xff0c;廣泛應用于移動應用、桌面應用及嵌入式系統。然而&#xff0c;SQLite 數據庫也面臨著安全挑戰&#x…