多線程和并發之線程

線程

前面講到進程:為了并發執行任務(程序),現代操作系統才引進進程的概念
分析:

  • 創建開銷問題:創建一個進程開銷:大

    • 子進程需要拷貝父進程的整個地址空間
  • 通信開銷問題:進程間的通信

    • 需要用第三方(如:內核
  • P1 -> copy -> 內核 -> copy -> P2

  • 進程間通信代價或者開銷也是很大的。進程的地址空間是獨立,要通信的話需要用第三方的空

  • 間。

于是,就有人提出能不能在 同一個(同一個進程內部)進程地址空間中進行任務的并發:線程/輕量級
進程

線程是一個比進程更小的活動單位。它是進程中的執行路徑(執行分支),線程也是并發的一種形式。
進程內部可以存在多個線程,它并發執行,但是進程內部的所有的線程共享整個進程的地址空間
main 函數:進程的主線程

1 線程特點

  • 創建一個線程要比創建進程開銷要小很多

    • 因為創建一個線程的話,不需要拷貝進程的地址空間
  • 實現線程間的通信會更加方便

    • 因為進程內部所有線程共享整個進程地址空間
  • 線程也是一個動態概念:

    • 線程(進程)狀態圖
      • 就緒態:ready
      • 運行態:running
      • 阻塞態:blocking

有了線程的概念之后

  • 系統的調度單位就從進程變為線程,資源的分配還是以進程為單位

線程是進程內部的一個指令的執行分支,多個線程就是多個指令序列并發執行。這些指令必須在函數
內部,線程的指令部分肯定是封裝一個函數的內部的。這個函數,就稱之為:線程函數,一個線程在創
建之后,要執行的指令全部封裝在該函數內部,這個線程函數執行完畢之后,該線程的任務也就執行完

2 線程函數的原型

typedef void *(*start_routine_t)(void *);// 函數指針:指向一個返回值為void*且帶有一個void*參數的函數
// 類型重定義:將一個函數指針類型重命名為start_routine_tvoid *my_thread(void *) // 咱自定義的線程函數:必須要符合返回值是void*且帶有void*參數的一
//個函數
{// 執行線程需要執行的代碼
}

3.Linux對線程的API的支持

Linux下采用的是POSIX Thread線程庫。簡稱為:pthread

示例

#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;string str = "你好,線程";
// 線程函數,表示線程啟動之后第一時間會執行的函數
void *mythread(void *arg)
{cout  << "子線程:"  << str << endl;return nullptr;
}int main()
{// 創建線程// 第一次參數,用來存儲線程的id號pthread_t tid;pthread_create(&tid, nullptr, mythread, nullptr);// 子線程先指向父線程再打印 保證子線程在父線程后面結束sleep(1);cout << "主線程:" << str << endl;return 0;
}

3.1 創建一個線程

pthread_create:創建一個線程(啟動一個線程)

 PTHREAD_CREATE(3)                                  Linux Programmer's Manual     PTHREAD_CREATE(3)NAMEpthread_create - create a new threadSYNOPSIS#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);/*@描述:創建一個新線程,啟動一個線程@thread:指向的空間,用來存儲線程的id號@attr:線程屬性:用于指定新創建的線程的一些屬性的。一般采用NULL,為默認屬性@start_routine:線程函數,表示線程啟動之后第一時間會執行的函數。也就是說新線程創建之后會指向start_routine函數內任務。@arg:參數,表示新線程要去start_routine執行任務,但是start_routine是一個函數。
start_routine是函數就可以有參數。所有arg實際上就是傳給start_routine的參數的。@return:成功返回0,失敗返回-1,同時errno被設置。*//*int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg){// 其他的代碼// 創建線程去執行start_routinestart_routine(arg);如果線程創建成功return 0;否則就是:return -1;}*/

示例

#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;string str = "你好,線程";
// 線程函數,表示線程啟動之后第一時間會執行的函數
void *mythread(void *arg)
{cout  << "子線程:"  << str << endl;return nullptr;
}int main()
{// 創建線程// 第一次參數,用來存儲線程的id號pthread_t tid;pthread_create(&tid, nullptr, mythread, nullptr);// 子線程先指向父線程再打印 保證子線程在父線程后面結束sleep(1);cout << "主線程:" << str << endl;return 0;
}

3.2 線程的退出

線程函數的退出(線程函數的返回)

 void *start_routine(void *arg){return nullptr; // 線程結束
}

在線程執行的任意時刻調用pthread_exit

 PTHREAD_EXIT(3)                                    Linux Programmer's Manual     PTHREAD_EXIT(3)NAMEpthread_exit - terminate calling threadSYNOPSIS#include <pthread.h>void pthread_exit(void *retval);/*@描述立即結束線程@retval:線程結束之后需要返回的參數,返回值的指針。*/

被別人干掉

  • cancel:被別人取消(其他線程調用pthread_cancel)

    • t1:pthread_cancel(t2)

    • t1調用取消函數,取消t2,t2不一定會被取消

      • 因為t2能不能被其他線程取消,取決于t2線程的一個屬性:取消屬性

      • 它是否可以被cancelled

 PTHREAD_CANCEL(3)                                  Linux Programmer's Manual     PTHREAD_CANCEL(3)NAMESYNOPSIS#include <pthread.h>int pthread_cancel(pthread_t thread);/*@描述:取消一個指定的線程@thread:線程號,需要取消的那個線程的id號@return:成功返回0,失敗返回非0.*/pthread_cancel - send a cancellation request to a thread
SYNOPSIS#include <pthread.h>int pthread_cancel(pthread_t thread);/*@描述:取消一個指定的線程@thread:線程號,需要取消的那個線程的id號@return:成功返回0,失敗返回非0.*/
  • 這個屬性叫做:可以被取消屬性
    • PTHREAD_CANCEL_ENABLE:表示該線程可以被取消
    • PTHREAD_CANCEL_DISABLE:表示該線程不能被取消
 PTHREAD_SETCANCELSTATE(3)                          Linux Programmer's Manual     PTHREAD_SETCANCELSTATE(3)NAMEpthread_setcancelstate, pthread_setcanceltype - set cancelability state 
and typeSYNOPSIS#include <pthread.h>int pthread_setcancelstate(int state, int *oldstate);/*@描述:設置線程取消屬性的@state: 設置線程的取消狀態PTHREAD_CANCEL_ENABLE:表示該線程可以被取消PTHREAD_CANCEL_DISABLE:表示該線程不能被取消@oldstate:線程上一次的取消狀態@return:成功返回0,失敗返回其他值*/  

一個線程退出了,并不是所有資源都會釋放。一個線程的退出,它資源釋放全部被釋放,取決于一個屬 性

示例

#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;string str = "你好,線程";
// 線程函數,表示線程啟動之后第一時間會執行的函數
void *mythread(void *arg)
{//  存儲的是調用前的狀態int old_state = 0;// 控制當前線程的可取消性 PTHREAD_CANCEL_DISABLE不能被取消 |PTHREAD_CANCEL_ENABLE可以被取消// pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,& old_state);cout << (old_state == PTHREAD_CANCEL_DISABLE? "不可以被取消":"可以被取消") << endl;while (1){cout  << "子線程:"  << str << endl;sleep(1);}return nullptr;
}int main()
{// 創建線程// 第一次參數,用來存儲線程的id號pthread_t tid;pthread_create(&tid, nullptr, mythread, nullptr);// 子線程先指向父線程再打印 保證子線程在父線程后面結束sleep(3);cout << "主線程:" << str << endl;pthread_cancel(tid);sleep(3);return 0;
}

3.3 資源分離

detach:分離屬性:

  • ENABLE: 分離資源屬性

    • 該線程結束,它的所有資源都會自動釋放。
  • DISABLE: 不分離資源

    • 該線程結束,會有部分資源不會自動釋放,需要其他線程調用pthread_join這個函數才能完

    全釋放

3.3.1 線程資源回收函數
PTHREAD_JOIN(3)                                                   Linux 
Programmer's Manual                                                   
PTHREAD_JOIN(3)NAMEpthread_join - join with a terminated threadSYNOPSIS#include <pthread.h>int pthread_join(pthread_t thread, void **retval);/*@描述:等待一個指定的線程結束 阻塞狀態@thread:需要等待的線程id號@retval:二級指針,表示線程函數的返回值指針@return:成功返回0失敗返回-1*/
3.3.2 資源分類屬性
 PTHREAD_DETACH(3)                                                 Linux 
Programmer's Manual                                                 
PTHREAD_DETACH(3)NAMEpthread_detach - detach a threadSYNOPSIS#include <pthread.h>int pthread_detach(pthread_t thread);/*@描述:設置線程的資源分離屬性@thread:需要設置資源分離屬性的那個線程id@return:成功返回0失敗返回-1*/
3.3.3 獲取自身ID號
#include <pthread.h>pthread_t pthread_self(void);/*
作用:
獲取當前所在線程的tid號
@return:
返回當前所在線程的tid號
*/

示例

#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;string str = "你好,線程";
// 線程函數,表示線程啟動之后第一時間會執行的函數
void *mythread(void *arg)
{pthread_detach(pthread_self());while (1){cout  << "子線程:"  << str << endl;sleep(1);}return nullptr;
}int main()
{// 創建線程// 第一次參數,用來存儲線程的id號pthread_t tid;pthread_create(&tid, nullptr, mythread, nullptr);cout << "主線程:" << str << endl;// 取消線程   pthread_cancel(tid);sleep(3);// 資源回收pthread_join(tid,nullptr);return 0;
}

4. 線程的同步/互斥機制

為了線程之間,能夠去有序的訪問共享資源,引用信號量機制

  • 信號量System VPOSIX 信號量
  • 線程互斥鎖

4.1 線程互斥鎖

線程互斥鎖也是信號量,只不過線程互斥鎖,存在于進程地址空間,用于線程間同步和互斥操作,線程
互斥鎖它的效率相對信號量來說要高。
線程互斥鎖:使用pthread_mutex_t 的類型來描述一個鎖
安裝線程POSIX 幫助手冊:sudo apt-get install manpages-posix-dev // 安裝posix 幫助手冊

  • 初始化線程互斥鎖
PTHREAD_MUTEX_INIT(3POSIX)                                             POSIX Programmer's 
Manual                             					PTHREAD_MUTEX_INIT(3POSIX)PROLOGThis  manual  page  is part of the POSIX Programmer's Manual.  The Linux 
implementation of this interface may differ (consult thecorresponding Linux manual page for details of Linux behavior), or the 
interface may not be implemented on Linux.NAMEpthread_mutex_init — destroy and initialize a mutexSYNOPSIS#include <pthread.h>int pthread_mutex_init(pthread_mutex_t *restrict mutex,const 
pthread_mutexattr_t *restrict attr);/*@描述:初始一個線程互斥鎖@mutex:需要初始化的線程互斥鎖地址pthread_mutex_t mutex; // 創建了一個互斥鎖	&mutex ---> 互斥鎖地址@attr:線程互斥鎖的屬性,一般為NULL,采用默認屬性如:線程的互斥鎖默認設置 1 unlock@return:成功返回0,失敗返回-1*/
  • 線程互斥鎖的PV操作
int pthread_mutex_lock(pthread_mutex_t *mutex);/*作用:死等上鎖,如果該鎖沒有被釋放,則會一直阻塞在此函數,等待該鎖被釋放。@mutex:需要上鎖的互斥鎖指針@return:成功返回0,表示獲取到了該互斥鎖返回-1,表示獲取出錯,沒有獲取到互斥鎖
*/int pthread_mutex_trylock(pthread_mutex_t *mutex);/*作用: 嘗試上鎖,嘗試性上鎖,如果該鎖沒被釋放,那么立即返回執行后面的代碼。@mutex:需要上鎖的互斥鎖指針@return:成功返回0,表示獲取到了該互斥鎖其他值,表示沒有獲取到互斥鎖
*/int pthread_mutex_timedlock(pthread_mutex_t *mutex,struct timespec 
*abs_timeout);
*abs_timeout);/*作用:限時上鎖,如果該鎖沒有被釋放,則會一直阻塞在此函數中一段實際,等待該鎖被釋放。如果時間
過了還沒有被釋放,那么果斷放棄執行后面的代碼。@mutex:需要上鎖的互斥鎖指針@abs_timeout:絕對時間(超時時間),上鎖的時間范圍。@return:成功返回0,表示獲取到了該互斥鎖其他值,表示沒有獲取到互斥鎖*/
  • V操作(解鎖操作)
int pthread_mutex_unlock(pthread_mutex_t *mutex);/*
作用:
解鎖線程互斥鎖
@mutex:
需要解鎖的線程互斥鎖指針
*/
  • 線程互斥鎖的銷毀操作
int pthread_mutex_destroy(pthread_mutex_t *mutex);/*作用:銷毀一個線程互斥鎖@mutex:需要銷毀的線程互斥鎖指針@return:成功返回0,失敗返回-1*/

5.生產者消費者模型

生產者消費者模型:利用廠商和消費者關系,由生產者線程進行生產(產生任務),再由消費者線程消 費(執行任務),沒有任務的時候,消費者等待生產者產生任務。

  • 共享資源的互斥訪問問題
    • 信號量/線程互斥鎖

當緩沖區(生產者沒有產出的時候)沒有數據的時候,(消費者)應該怎么辦?

  • 不停的去測試,看有沒有數據。

    • 輪詢訪問,但是輪詢有缺陷:一直在訪問,浪費CPU資源。輪詢有時間差,占用總線:`Is ``

      always busy

  • 讓出CPU,當有數據的時候,再喚醒我(wake up),線程條件變量:同步

5.1 線程條件變量

線程條件變量:在多線程程序設計中,可以用條件變量為表示一個特定的條件或者是事件
pthread_cond_t :來描述一個條件變量(類型)
至于條件變量,到底是一個什么事件或者說表示一個什么條件?完全由程序猿去解釋這個條件變量所代
表的含義。
在條件變量上的三種操作:

  • 初始化
  • 等待一個條件變量(等待該條件變量所表示的事件)
  • 喚醒一個線程/觸發條件變量(喚醒了正在等待該事件的線程)
int data = 0;main : 主線程:生產者:包工頭data = 1;t1:子線程:消費者:牛馬when data == 1;干活data = 0; 

5.2 線程條件變量 API

5.2.1 初始化/銷毀條件變量
PTHREAD_COND_DESTROY(3POSIX)                                      		POSIX 
Programmer's Manual                                      
PTHREAD_COND_DESTROY(3POSIX)PROLOGThis  manual  page  is  part of the POSIX Programmer's Manual.  The Linux 
implementation of this interface may differ (consult the corresponding Linuxmanual page for details of Linux behavior), or the interface may not be 
implemented on Linux.NAMEpthread_cond_destroy, pthread_cond_init — destroy and initialize 
condition variablesSYNOPSIS#include <pthread.h>int pthread_cond_destroy(pthread_cond_t *cond);/*@描述:銷毀一個條件變量@cond:需要銷毀條件變量指針
*/
  int pthread_cond_init(pthread_cond_t *restrict cond,const 
pthread_condattr_t *restrict attr);/*@描述:初始化一個條件變量@cond:需要初始化的條件變量的指針@attr:初始化的條件變量的屬性,一般為NULL,采用默認設置@return:成功返回0,失敗返回其他值*/
5.2.2 等待一個條件變量
 PTHREAD_COND_TIMEDWAIT(3POSIX)                                    POSIX 
Programmer's Manual                                    
PTHREAD_COND_TIMEDWAIT(3POSIX)PROLOGThis  manual  page  is  part of the POSIX Programmer's Manual.  The Linux 
implementation of this interface may differ (consult the corresponding Linuxmanual page for details of Linux behavior), or the interface may not be 
implemented on Linux.NAMEpthread_cond_timedwait, pthread_cond_wait — wait on a conditionSYNOPSIS#include <pthread.h>int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t 
*restrict mutex,const struct timespec *restrict abstime);/*@描述:限時等待條件變量@cond:需要等待的那個條件變量指針@mutex:線程互斥鎖:為了保護cond所表示的那個事件/共享資源的。條件變量實際也是一個共享資源。@abstime:絕對時間,需要被喚醒的絕對時間*/int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t 
*restrict mutex);/*@描述:等待那個條件變量@cond:需要等待的那個條件變量指針@mutex:線程互斥鎖:為了保護cond所表示的那個事件/共享資源的。條件變量實際也是一個共享資源。@abstime:絕對時間,需要被喚醒的絕對時間*/int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t 
*restrict mutex);/*@描述:等待那個條件變量@cond:需要等待的那個條件變量指針@mutex:線程互斥鎖:為了保護cond所表示的那個事件/共享資源的。條件變量實際也是一個共享資源。mutex:locked 上鎖pthread_cond_wait(){... 準備工作mutex:unlock 解鎖讓出CPU 等待...when 當條件產生的時候,其他的線程喚醒我的時候mutex:locked 上鎖}@return:成功返回0,被其他線程喚醒失敗返回其他值*/
5.3.3 喚醒線程/觸發條件變量
PTHREAD_COND_BROADCAST(3POSIX)                                    POSIX 
Programmer's Manual                                    
PTHREAD_COND_BROADCAST(3POSIX)PROLOGThis  manual  page  is  part of the POSIX Programmer's Manual.  The Linux 
implementation of this interface may differ (consult the corresponding Linuxmanual page for details of Linux behavior), or the interface may not be 
implemented on Linux.NAMEpthread_cond_broadcast, pthread_cond_signal — broadcast or signal a 
conditionSYNOPSIS#include <pthread.h>// 廣播喚醒int pthread_cond_broadcast(pthread_cond_t *cond);/*@描述:喚醒所有正在等待的線程@cond:那個條件變量@return:成功返回0,失敗返回其他值*/// 單個喚醒int pthread_cond_signal(pthread_cond_t *cond);/*@描述:只喚醒一個線程在等待的線程。@cond:那個條件變量@return:成功返回0,失敗返回其他值*/

注意:廣播喚醒和單個喚醒的區別

  • 廣播喚醒:喚醒所有等待的線程,去執行任務,但是任務可能不夠分,那么沒分到的線程繼續休眠
  • 單個喚醒:隨機喚醒一個線程執行任務,其他線程繼續休眠。
#include <iostream>
#include <vector>
#include <unistd.h>
#include <pthread.h>// 全局變量供父子線程使用
int a = 0;
int b = 0;
// 線程互斥鎖
pthread_mutex_t mutex;
// 條件變量
pthread_cond_t cond;
void *myrhtread(void *arg)
{usleep(10);std::cout << "子線程:" << pthread_self() << "啟動完成" << std::endl;while (1){// 上鎖pthread_mutex_lock(&mutex);// 休息,等待主線程給活,沒有就休息等待pthread_cond_wait(&cond, &mutex);//if (a < 0 && b < 0){//小于0時候退先解鎖在退出pthread_mutex_unlock(&mutex);break;}std::cout << "子線程:" << pthread_self()  << "計算結果是:" << a + b << std::endl;// 解鎖pthread_mutex_unlock(&mutex);}return nullptr;
}
int main()
{// 初始化互斥鎖pthread_mutex_init(&mutex, nullptr);// 初始化條件變量pthread_cond_init(&cond, nullptr);// 定義五個工作者(牛馬)std::vector<pthread_t> works;// 創建線程for (int i = 0; i < 5; i++){pthread_t tid;pthread_create(&tid, nullptr, myrhtread, nullptr);// 添加到容器里面works.push_back(tid);}usleep(10);// 生產者while (1){// 上鎖pthread_mutex_lock(&mutex);std::cout << "請輸入" << std::endl;std::cin >> a >> b;// 退出條件if(a < 0 && b < 0){pthread_mutex_unlock(&mutex);break;}// 解鎖pthread_mutex_unlock(&mutex);// 喚醒線程可以工作了pthread_cond_signal(&cond);usleep(10);}// 喚醒全部線程逐步退出pthread_cond_broadcast(&cond);// 等待工作者線程結束for(pthread_t tid:works){pthread_join(tid, nullptr);}// 銷毀條件變量pthread_cond_destroy(&cond);// 銷毀鎖pthread_mutex_destroy(&mutex);
}

在這里插入圖片描述

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

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

相關文章

AAAI 2025論文分享│STD-PLM:基于預訓練語言模型的時空數據預測與補全方法

本文詳細介紹了一篇發表于人工智能頂級會議AAAI 2025的論文《STD-PLM: Understanding Both Spatial and Temporal Properties of Spatial-Temporal Data with PLM》。該論文提出了一種基于預訓練語言模型&#xff08;Pre-trained Language Model?&#xff0c;PLM&#xff09;的…

前端八股 tcp 和 udp

都是傳輸層協議 udp 數據報協議 不可靠面向數據包對于應用層傳遞的報文加上UDP首部就傳給網絡層 tcp 傳輸控制協議 可靠 會將報文分段進行傳輸 區別&#xff1a; 1.tcp 可靠 udp 不可靠 2.tcp 面向連接 三握四揮 udp 無連接 3.tcp面向字節流 udp面向報文 4.效率低 效率高…

MES管理系統:Java+Vue,含源碼與文檔,實現生產過程實時監控、調度與優化,提升制造企業效能

前言&#xff1a; 在當今競爭激烈的制造業環境中&#xff0c;企業面臨著提高生產效率、降低成本、提升產品質量以及快速響應市場變化等多重挑戰。MES管理系統作為連接企業上層計劃管理系統與底層工業控制之間的橋梁&#xff0c;扮演著至關重要的角色。它能夠實時收集、分析和處…

MSTNet:用于糖尿病視網膜病變分類的多尺度空間感知 Transformer 與多實例學習方法|文獻速遞-深度學習醫療AI最新文獻

Title 題目 MSTNet: Multi-scale spatial-aware transformer with multi-instance learning for diabetic retinopathy classification MSTNet&#xff1a;用于糖尿病視網膜病變分類的多尺度空間感知 Transformer 與多實例學習方法 01 文獻速遞介紹 糖尿病視網膜病變&#…

每日八股文6.2

每日八股-6.2 Go1.GMP調度原理&#xff08;這部分多去看看golang三關加深理解&#xff09;2.GC&#xff08;同樣多去看看golang三關加深理解&#xff09;3.閉包4.go語言函數是一等公民是什么意思5.sync.Mutex和sync.RWMutex6.sync.WaitGroup7.sync.Cond8.sync.Pool9.panic和rec…

【Unity】相機 Cameras

1 前言 主要介紹官方文檔中相機模塊的內容。 關于“9動態分辨率”&#xff0c;這部分很多API文檔只是提了一下&#xff0c;具體細節還需要自己深入API才行。 2 攝像機介紹 Unity 場景在三維空間中表示游戲對象。由于觀察者的屏幕是二維屏幕&#xff0c;Unity 需要捕捉視圖并將…

SpringBoot(六)--- AOP、ThreadLocal

目錄 前言 一、AOP基礎 1.入門程序 2. AOP核心概念 3. 底層原理 二、AOP進階 1.通知類型 抽取切入點 2. 切入點表達式 2.1 execution 2.2 annoation 2.3 連接點詳解 三、ThreadLocal 前言 AOP&#xff08;面向切面編程&#xff09;&#xff0c;面向切面編程實際就…

【深度學習】 19. 生成模型:Diffusion Models

Diffusion Models Diffusion Models 簡介 Diffusion 模型是一類通過逐步添加噪聲并再逆向還原的方式進行圖像生成的深度生成模型。其基本流程包括&#xff1a; 前向過程&#xff08;Forward Process&#xff09;&#xff1a;將真實圖像逐步加噪&#xff0c;最終變為高斯噪聲…

Y1——鏈式前向星

知識點 模版——鏈表的前插法 head表示頭結點的下標 ver[i]表示結點i 的值 tot存儲當前已經用到了哪個 add用于將x插到頭結點 int head1; intt ver[N],Next[N]; int ttot-1; void add(int x){ver[tot]x;Next[tot]head;headtot; } 常見的鏈式前向星三種實現形式&#xff…

如何排查Redis單個Key命中率驟降?

問題現象 Redis整體命中率98%&#xff0c;但監控發現特定Key&#xff08;如user:1000:profile&#xff09;的命中率從99%驟降至40%&#xff0c;引發服務延遲上升。 排查步驟 1. 確認現象與定位Key // 通過Redis監控工具獲取Key指標 public void monitorKey(String key) {Je…

自定義Shell命令行解釋器

目錄 1、目標 2、顯示命令提示符 2.1 getenv 2.2 getcwd 2.3 putenv 3、獲取用戶輸入的命令 4、解析命令 5、處理內建命令 6、處理外部命令 7、完整代碼 7.1 myshell.cpp 7.2 Makefile 1、目標 實現一個Linux的myshell&#xff0c;有以下基本的功能。 顯示命令提示…

Laplace 噪聲

Laplace 噪聲是一種特定概率分布&#xff08;拉普拉斯分布&#xff09;產生的隨機擾動。它是差分隱私&#xff08;Differential Privacy, DP&#xff09;中最核心、最常用的噪聲機制之一。它的核心作用是在不泄露個體信息的前提下&#xff0c;允許從包含敏感數據的數據庫中提取…

基于空天地一體化網絡的通信系統matlab性能分析

目錄 1.引言 2.算法仿真效果演示 3.數據集格式或算法參數簡介 4.MATLAB核心程序 5.算法涉及理論知識概要 5.1 QPSK調制原理 5.2 空天地一體化網絡信道模型 5.3 空天地一體化網絡信道特性 6.參考文獻 7.完整算法代碼文件獲得 1.引言 空天地一體化網絡是一種將衛星通信…

【Delphi】接收windows文件夾中文件拖拽

本文根據EmailX45的視頻文件&#xff0c;進行了優化改進&#xff0c;原文參見&#xff1a;Delphi: Drag and Drop Files from Explorer into TPanel / TMemo - YouTube 在Windows中&#xff0c;如果將選擇的文件拖動到Delphi程序的控件上&#xff0c;有很多實現方法&#xff0c…

基于熱力學熵增原理的EM-GAN

簡介 簡介:提出基于熱力學熵增原理的EM-GAN,通過生成器熵最大化約束增強輸出多樣性。引入熵敏感激活函數與特征空間熵計算模塊,在MNIST/CelebA等數據集上實現FID分數提升23.6%,有效緩解模式崩潰問題。 論文題目:Entropy-Maximized Generative Adversarial Network (EM-G…

HashMap與ConcurrentHashMap詳解:實現原理、源碼分析與最佳實踐

引言 在Java編程中&#xff0c;集合框架是最常用的工具之一&#xff0c;而HashMap和ConcurrentHashMap則是其中使用頻率最高的兩個Map實現。它們都用于存儲鍵值對數據&#xff0c;但在實現機制、性能特點和適用場景上有著顯著差異。 HashMap作為單線程環境下的首選Map實現&am…

CSS之動畫(奔跑的熊、兩面反轉盒子、3D導航欄、旋轉木馬)

一、 2D轉換 1.1 transform: translate( ) 轉換&#xff08;transform&#xff09; 是CSS3中具有顛覆性的特征之一&#xff0c;可以實現元素的位移、旋轉、縮放等效果 移動&#xff1a;translate 旋轉&#xff1a;rotate 縮放&#xff1a;scale 下圖為2D轉換的坐標系 回憶…

【筆記】在 MSYS2(MINGW64)中安裝 python-maturin 的記錄

#工作記錄 &#x1f4cc; 安裝背景 操作系統&#xff1a;MSYS2 MINGW64當前時間&#xff1a;2025年6月1日Python 版本&#xff1a;3.12&#xff08;通過 pacman 安裝&#xff09;目標工具&#xff1a;maturin —— 用于構建和發布 Rust 編寫的 Python 包 &#x1f6e0;? 安裝…

基于微信小程序的垃圾分類系統

博主介紹&#xff1a;java高級開發&#xff0c;從事互聯網行業六年&#xff0c;熟悉各種主流語言&#xff0c;精通java、python、php、爬蟲、web開發&#xff0c;已經做了六年的畢業設計程序開發&#xff0c;開發過上千套畢業設計程序&#xff0c;沒有什么華麗的語言&#xff0…

工作日記之權限校驗-token的實戰案例

背景說明 我們組負責維護的一個系統&#xff0c;前端界面掛載在其他兩個系統上&#xff0c;因為歷史遺留原因&#xff0c;同時也掛在公網上&#xff0c;沒有登陸功能和用戶體系&#xff0c;只要輸入網址就能訪問&#xff0c;雖然這個系統是給公司內部人員使用&#xff0c;但是…