Linux 高級編程——線程控制


線程控制:互斥與同步

概念:
?? ?互斥 ===》在多線程中對臨界資源排他性訪問。

?? ?互斥機制 ===》互斥鎖 ?===》保證臨界資源的 訪問控制。

?? ?pthread_mutex_t ? mutex;
?? ?互斥鎖類型 ? ? ? ?互斥鎖變量 內核對象

?? ?框架:
?? ? 定義互斥鎖 ==》初始化鎖 ==》加鎖 ==》解鎖 ==》銷毀
?? ??? ?**** ? ? ? ? ? ? ? ? ? ? ?*** ? ? ?***

?? ? 1、定義:
?? ??? ?pthread_mutex_t ? mutex;

?? ? 2、初始化鎖
?? ??? ?int pthread_mutex_init(
?? ??? ??? ?pthread_mutex_t *mutex,
?? ??? ??? ?const pthread_mutexattr_t *attr);
?? ??? ?功能:將已經定義好的互斥鎖初始化。
?? ??? ?參數:mutex 要初始化的互斥鎖
?? ??? ??? ? ?atrr ?初始化的值,一般是NULL表示默認鎖
?? ??? ?返回值:成功 0
?? ??? ??? ??? ?失敗 非零
?? ? 3、加鎖:
?? ??? ?int pthread_mutex_lock(pthread_mutex_t *mutex);
?? ??? ?功能:用指定的互斥鎖開始加鎖代碼
?? ??? ??? ? ?加鎖后的代碼到解鎖部分的代碼屬于原子操作
?? ??? ??? ? ?在加鎖期間其他進程/線程都不能操作該部分代碼
?? ??? ??? ? ?如果該函數在執行的時候,mutex已經被其他部分
?? ??? ??? ? ?使用則代碼阻塞。

?? ??? ?參數: mutex 用來給代碼加鎖的互斥鎖
?? ??? ?返回值:成功 0
?? ??? ??? ??? ?失敗 非零

?? ? 4、解鎖
?? ??? ?int pthread_mutex_unlock(pthread_mutex_t *mutex);
?? ??? ?功能:將指定的互斥鎖解鎖。
?? ??? ??? ? ?解鎖之后代碼不再排他訪問,一般加鎖解鎖同時出現。
?? ??? ?參數:用來解鎖的互斥鎖
?? ??? ?返回值:成功 0
?? ??? ??? ??? ?失敗 非零

?? ? 5、銷毀
?? ??? ? int pthread_mutex_destroy(pthread_mutex_t *mutex);
?? ??? ? 功能:使用互斥鎖完畢后需要銷毀互斥鎖
?? ??? ? 參數:mutex 要銷毀的互斥鎖
?? ??? ? 返回值:成功 ?0
?? ??? ??? ??? ? 失敗 ?非零

?? ? 6、trylock
?? ??? ?int pthread_mutex_trylock(pthread_mutex_t *mutex);
?? ??? ?功能:類似加鎖函數效果,唯一區別就是不阻塞。
?? ??? ?參數:mutex 用來加鎖的互斥鎖
?? ??? ?返回值:成功 0
?? ??? ??? ??? ?失敗 非零
?? ??? ??? ??? ?E_AGAIN

注意:

被互斥鎖包含的地方盡量簡短

鎖的位置就是要小,盡可能做到并發

互斥鎖中不會吧延遲函數鎖上

上了鎖的地方一定要檢查某些地方解鎖了沒。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>int a = 0;
pthread_mutex_t mutex;
void* th(void* arg)
{// pthread_mutex_lock(&mutex);int i =5000;while(i--){pthread_mutex_lock(&mutex);int tmp = a;printf("a is %d\n",tmp+1);a = tmp+1;pthread_mutex_unlock(&mutex); }// pthread_mutex_unlock(&mutex); return NULL;
}int main(int argc, char *argv[])
{pthread_t tid1,tid2;pthread_mutex_init(&mutex,NULL);pthread_create(&tid1,NULL,th,NULL);pthread_create(&tid2,NULL,th,NULL);pthread_join(tid1,NULL);pthread_join(tid2,NULL);pthread_mutex_destroy(&mutex);return 0;
}

十個人來銀行辦業務,
?? ?int a ?= 0 ;
?? ?
?? ?while(5000--)
?? ?{
?? ??? ?int temp = a;
?? ??? ?printf("%d",temp+1);
?? ??? ?a =temp+1;
?? ?}

?? ??? ?get win ? sleep(rand()%5);
?? ??? ?get win
?? ??? ?get win?
?? ??? ?leave?
?? ??? ??
?? ?10線程,
?? ?count = 3,
?? ?th()
?? ?{
?? ?while(1)
?? ?{
?? ??? ?if( cout >0 )
?? ??? ?{?? ?
?? ??? ??? ?//you
?? ??? ??? ?printf("get totile\n");
?? ??? ??? ?cout--;
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?//sleep(1);
?? ??? ?}
?? ?}
?? ?rand()%5
?? ??? ?sleep(5)
?? ??? ?printf("release totile\n")
?? ??? ?coutt++;
?? ?}
?? ?main()
?? ?{
?? ??? ?pthread_create*10;
?? ??? ?pthread_join();*10
?? ?}
?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
pthread_mutex_t mutex;
int WIN = 3;
void* th(void* arg)
{while(1){pthread_mutex_lock(&mutex);if(WIN>0){WIN--;pthread_mutex_unlock(&mutex);printf("get win\n");sleep(rand()%5);printf("relese win\n");pthread_mutex_lock(&mutex);WIN++;pthread_mutex_unlock(&mutex);break;}else {pthread_mutex_unlock(&mutex);}}return NULL;
}int main(int argc, char *argv[])
{pthread_t tid[10];int i = 0 ;pthread_mutex_init(&mutex,NULL);for(i = 0 ;i<10;i++){pthread_create(&tid[i],NULL,th,NULL);}for(i = 0 ;i<10;i++){pthread_join(tid[i],NULL);}pthread_mutex_destroy(&mutex);return 0;
}

? ??? ??? ??? ?
?? ??? ??? ??? ?
?? ?練習:
?? ??? ?設計一個多線程程序,共享同一塊字符數組,分別向該
?? ??? ?數組中寫入字符串,保證某一時刻只能有一個線程在操作
?? ??? ?該數組,使用堆區/棧區互斥鎖來保證排他性訪問。
?? ??? ?
?? ?練習2:
?? ?使用互斥鎖完成如下功能:
?? ?設計多線程程序,同時對指定的文件進行寫操作
?? ?要求每個線程寫入的信息不能覆蓋和交叉。
?? ?文件中的數據要是輸入信息的總和不能丟失。
? ?
??

?線程的同步 ===》同步?
? ===》有一定先后順序的對資源的排他性訪問。

?? ?原因:互斥鎖可以控制排他訪問但沒有次序。

?? ?linux下的線程同步 ?===》信號量機制 ===》semaphore.h ? posix?
?? ?sem_open();

信號量是內核中的操作,
?? ?信號量的分類:
?? ?1、無名信號量 ==》線程間通信
?? ?2、有名信號量 ==》進程間通bn

?? ?

框架:
?? ?信號量的定義 ===》信號量的初始化 ==》信號量的PV操作
?? ?===》信號量的銷毀。

?? ?semaphore?
?? ?1、信號量的定義 :
?? ? ? sem_t ? ? ? ? ? ?sem;
?? ? ? 信號量的類型 ? ? 信號量的變量

?? ?2、信號量的初始化
?? ??? ?int sem_init(sem_t *sem, int pshared, unsigned int value);
?? ??? ?功能:將已經定義好的信號量賦值。
?? ??? ?參數:sem 要初始化的信號量
?? ??? ??? ? ?pshared = 0 ;表示線程間使用信號量
?? ??? ??? ??? ??? ? ?!=0 ;表示進程間使用信號量
?? ??? ??? ? ?value 信號量的初始值,一般無名信號量
?? ??? ??? ? ?都是二值信號量,0 1?
?? ??? ??? ? ?0 表示紅燈,進程暫停阻塞
?? ??? ??? ? ?1 表示綠燈,進程可以通過執行
?? ??? ?返回值:成功 ?0
?? ??? ??? ??? ?失敗 ?-1;
?? ?3、信號量的PV 操作
?? ? ? P ===》申請資源===》申請一個二值信號量?
?? ? ? V ===》釋放資源===》釋放一個二值信號量

二值信號量;0或者1;

?? ? ? P操作對應函數 ==》sem_wait();
?? ? ? V操作對應函數 ==》sem_post();

需要進行交叉操作。申請自己的,釋放對方的。

?? ?int sem_wait(sem_t *sem);
?? ?功能:判斷當前sem信號量是否有資源可用。
?? ??? ? ?如果sem有資源(==1),則申請該資源,程序繼續運行
?? ??? ? ?如果sem沒有資源(==0),則線程阻塞等待,一旦有資源
?? ??? ? ?則自動申請資源并繼續運行程序。

?? ??? ? ?注意:sem 申請資源后會自動執行 sem = sem - 1;
?? ?參數:sem 要判斷的信號量資源
?? ?返回值:成功 0?
?? ??? ??? ?失敗 -1
?? ??? ?
?? ?int sem_post(sem_t *sem);
?? ?功能:函數可以將指定的sem信號量資源釋放
?? ??? ? ?并默認執行,sem = sem+1;
?? ??? ? ?線程在該函數上不會阻塞。
?? ?參數:sem 要釋放資源的信號量
?? ?返回值:成功 0
?? ??? ??? ?失敗 -1;

?? ?4、信號量的銷毀
?? ? ? int sem_destroy(sem_t *sem);
?? ? ? 功能:使用完畢將指定的信號量銷毀
?? ? ? 參數:sem要銷毀的信號量
?? ? ? 返回值:成功 0
?? ??? ??? ??? ?失敗 ?-1;

? 實現先打印hello,緊接著打印world

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem_H,sem_W;
void* th1(void* arg)
{int i =10;while(i--){sem_wait(&sem_H);printf("hello");fflush(stdout);sem_post(&sem_W);}return NULL;
}
void* th2(void* arg)
{int i =10;while(i--){sem_wait(&sem_W);printf(",world\n");sleep(1);sem_post(&sem_H);}return NULL;
}int main(int argc, char *argv[])
{pthread_t tid1,tid2;sem_init(&sem_H,0,1);sem_init(&sem_W,0,0);pthread_create(&tid1,NULL,th1,NULL);pthread_create(&tid2,NULL,th2,NULL);pthread_join(tid1,NULL);pthread_join(tid2,NULL);sem_destroy(&sem_H);sem_destroy(&sem_W);return 0;
}

?實現銀行示例用信號量。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem_WIN;
void* th(void* arg)
{sem_wait(&sem_WIN);printf("get win\n");sleep(rand()%5);printf("relese win\n");sem_post(&sem_WIN);return NULL;
}int main(int argc, char *argv[])
{srand(time(NULL));pthread_t tid[10];int i = 0 ;//計數信號量sem_init(&sem_WIN,0,3);for(i = 0 ;i<10;i++){pthread_create(&tid[i],NULL,th,NULL);}for(i = 0 ;i<10;i++){pthread_join(tid[i],NULL);}sem_destroy(&sem_WIN);return 0;
}


?? ?pthread_attr_t attr;
?? ?int pthread_attr_init(pthread_attr_t *attr);

? int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachst
ate)
功能:設置線程為分離的屬性,線程自己在消亡的時候,釋放相關的資源。
?? ?attr,出參,由該函數填充。
?? ?detachstate
?? ??? ?PTHREAD_CREATE_DETACHED:
?? ??? ?設置分離屬性的標記
?? ??? ?PTHREAD_CREATE_JOINABLE:
?? ??? ?設置關聯的屬性:
?? ??? ?
?? ??? ?返回 ?0 成功
?? ??? ? ? ? ?>0 失敗,以及錯誤號
?? ??? ??? ? ?
?? ??? ??? ? ?
?? ??? ??? ? ?
?? ?int pthread_detach(pthread_t thread);
?? ?功能:設置線程為分離的屬性,線程自己在消亡的時候,釋放相關的資源。
?? ?參數:thread,需要設置分離屬性的tid
?? ?

?? ??? ?返回 ?0 成功
?? ??? ? ? ? ?>0 失敗,以及錯誤號
?? ??? ??? ? ?
?? ?pthread_yield();usleep(1000);
?? ?功能:本線程放棄cpu的調度。
?? ?
?? ?
?? ?
?? ?
?? ?
?? ?
?? ?abcabcabcabc
?? ?AAABBBCCC
?? ?
?? ?3~5, 100
?? ?
?? ?
?? ?6線程, mallco 3?
?? ?int mem[3];//1. 0,
?? ?sem_mem 3;
?? ?int mymall0c()
?? ?{
?? ??? ?wait(sem_mem);
?? ??? ?for(i == 0;i<3;i++)
?? ??? ?if( m[i] == 1)?
?? ??? ?return i;
?? ?}
?? ?void myfree(id)
?? ?{
?? ??? ?mem[id]=1;
?? ??? ?sem_post(sem_mem);
?? ?}
?? ?void* th(void* age)?? ?
?? ?{
?? ??? ?int id = mymalloc();
?? ??? ?printf(我拿到di i 個空間);
?? ??? ?sleep(rand()%5);
?? ??? ?
?? ??? ?myfree(id);
?? ??? ?
?? ?
?? ?
?? ?}
?? ?
?? ?main()
?? ?{
?? ?
?? ??? ?pthread_create();//6
?? ??? ?ptread_join();//6
?? ?}
?? ?
?? ?
?? ?
?? ?1,服務員, 3桌子
?? ?
?? ??? ??? ??? ??? ?20
?? ?1,前臺,報菜單, ?name,號。
?? ?當前叫號,10,
?? ?sturct()
?? ?{
?? ??? ?name【100】,
?? ??? ?total_num;
?? ??? ?call_num;
?? ??? ?mutex_lock;
?? ?}
?? ?record;
?? ?customer)()
?? ?{
?? ??? ?printf("eat...");
?? ??? ?sleep();
?? ??? ?printf("out");
?? ??? ?sem_post();
?? ?}
?? ?
?? ?waiter()
?? ?{
?? ??? ?while(1)
?? ??? ?{
?? ??? ?wait(desk) ? ?8 ? ? ?10
?? ??? ?if ()//有人 ?call < total
?? ??? ?pthread_create(aa);
?? ??? ?else
?? ??? ?{
?? ??? ??? ?
?? ??? ?}
?? ?}
?? ?}
?? ?main()
?? ?{
?? ?
?? ??? ?pthread_create();//wait
?? ??? ?
?? ??? ?while()
?? ??? ?fgets,name, total++;
?? ??? ?
?? ?}
?? ?
?? ?

互斥鎖(Mutex)和信號量(Semaphore)都是多線程編程中用于實現資源共享和線程同步的機制,但它們在應用場景、實現方式和性能特點上有所不同。以下是它們之間的區別和相同點的詳細解釋:

區別

  1. 應用場景
    • 互斥鎖主要用于線程互斥,確保同一時刻只有一個線程能訪問特定的資源,防止資源被多個線程同時訪問。
    • 信號量主要用于線程同步,控制對共享資源的訪問許可。當資源可用時,允許線程繼續操作;當資源被占用時,線程則阻塞直到資源變得可用。
  2. 實現方式
    • 互斥鎖的值通常只能為0或1,表示資源是否被鎖定。當一個線程獲取互斥鎖時,其他試圖訪問該資源的線程將被阻塞,直到鎖被釋放。
    • 信號量的值可以是任意非負整數,表示可用資源的數量。當信號量的值大于0時,表示有可用資源,線程可以繼續操作;當信號量的值為0時,表示沒有可用資源,線程需要阻塞直到資源變得可用。
  3. 性能特點
    • 互斥鎖在鎖定資源時,所有試圖訪問該資源的線程都會被阻塞,直到資源被解鎖。它的實現相對簡單,效率較高,但在鎖爭用激烈的場景下,可能會帶來較大的性能開銷。
    • 信號量在資源被鎖定時,允許其他線程繼續執行某些任務,直到資源被釋放。因此,它更適用于需要等待時間較長的臨界區。同時,信號量還可以用于進程間通信,而互斥鎖僅用于線程間通信。
  4. 所有權特性
    • 互斥鎖具有明確的所有權特性,即同一時間只能有一個任務持有互斥鎖,而且只有這個任務可以對互斥鎖進行解鎖。
    • 信號量并沒有明確的所有權特性,一個進程阻塞在某個信號量上時,它無法知道自己阻塞在哪個進程(線程)之上。

相同點

  1. 重要性:對于線程來說,互斥鎖和信號量都是非常重要的概念,它們都可以避免死鎖或者讀臟數據。
  2. 目的:兩者的主要目的都是為了保護共享資源,確保線程在訪問這些資源時的正確性和一致性。
  3. 基本機制:它們都采用了某種形式的鎖定機制來防止多個線程同時訪問共享資源。

總結來說,互斥鎖和信號量在多線程編程中各有其應用場景和優缺點。在選擇使用哪種機制時,需要根據具體的需求和場景進行權衡和選擇。

?? ?
?? ?
?? ?
?? ?產生死鎖的原因主要是:

(1) 因為系統資源不足。
(2) 進程運行推進的順序不合適。
(3) 資源分配不當等。
如果系統資源充足,進程的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則
就會因爭奪有限的資源而陷入死鎖。其次,進程運行推進順序與速度不同,也可能產生死鎖。
產生死鎖的四個必要條件
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。優先級問題
(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
?

死鎖的原因
?

系統資源不足:當系統中的資源不足以滿足所有進程的需求時,進程之間可能會因為爭奪資源而產生死鎖。
進程運行推進的順序不合適:即使系統資源充足,如果進程請求資源的順序不當,也可能導致死鎖。例如,進程A擁有資源1并請求資源2,而進程B擁有資源2并請求資源1,此時就可能出現循環等待,導致死鎖。
資源分配不當:資源分配策略的不當也可能導致死鎖。例如,某些資源分配算法可能傾向于將資源分配給某些進程,而忽略其他進程的需求,從而增加了死鎖的風險。

死鎖的四個必要條件


互斥條件(Mutual Exclusion):一個資源每次只能被一個進程使用。即資源是獨占的,當一個進程持有一個資源時,其他進程不能同時訪問它。


請求與保持條件(Hold and Wait):一個進程因請求資源而阻塞時,對已獲得的資源保持不放。即進程已經持有一些資源,但又提出了新的資源請求,而該資源又被其他進程占有,此時請求進程阻塞,但又對自己持有的資源保持不放。


不剝奪條件(No Preemption):進程已獲得的資源,在末使用完之前,不能強行剝奪。即資源只能由獲得它的進程自己來釋放,進程之間不能相互剝奪對方的資源。


循環等待條件(Circular Wait):若干進程之間形成一種頭尾相接的循環等待資源關系。即存在一個等待資源的循環鏈,鏈中每個進程已獲得的資源同時被鏈中下一個進程所請求。


只有當這四個條件同時成立時,系統中才可能發生死鎖。因此,在設計和實現并發系統時,通常會采取一些策略來避免或解決死鎖問題,如預防策略(破壞四個條件中的至少一個)、避免策略(在資源分配之前判斷是否會導致死鎖)、檢測和恢復策略(允許死鎖發生,但系統能夠檢測到死鎖并采取相應的措施來恢復)。

??

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

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

相關文章

前端——在本地搭建Vue單頁應用

目錄 1、安裝最新node.js 2、打開命令行窗口 3、進入要保存項目的目錄下 4、安裝 Vue CLI 5、創建新項目&#xff0c;選擇功能 5.1 新建項目 5.2 Please pick a preset 5.3 Check the features needed for your project 5.4 Choose a version of Vue.js 5.5 Use hist…

Android13 串口控制是能wifi adb實現

Android13 串口控制是能wifi adb實現 文章目錄 一、前言二、Android 串口控制是能wifi adb實現1、通過Settings屬性控制2、通過prop屬性控制3、wifi adb 對應的Settings屬性和prop屬性關系&#xff08;1&#xff09;屬性監聽&#xff08;2&#xff09;相關代碼位置&#xff08;…

優化數據庫字段使用位運算-php語言示例

背景&#xff1a;一個會員有三個狀態&#xff0c;A、B、C&#xff0c;其中一個人可以為 A、B、C、AB&#xff1b;之前數據表結構加了三個字段is_a、is_b、is_c; 本人實在不想這樣粗糙的實現需求&#xff0c;遂決定用位運算優化。 上代碼&#xff1a; 位運算可以用來處理狀態值…

探索SOLIDWORKS 2024設計增強功能

隨著技術的不斷進步和市場的日益競爭&#xff0c;工程設計和制造行業對于快捷、準確和創新的工具需求日益增長。SOLIDWORKS作為3D CAD設計軟件&#xff0c;一直致力于為用戶提供更強大、更便捷的設計工具。SOLIDWORKS 2024的發布&#xff0c;再次證明了其在設計增強功能方面的持…

使用 Amazon Bedrock Converse API 簡化大語言模型交互

本文將介紹如何使用 Amazon Bedrock 最新推出的 Converse API&#xff0c;來簡化與各種大型語言模型的交互。該 API 提供了一致的接口&#xff0c;可以無縫調用各種大型模型&#xff0c;從而消除了需要自己編寫復雜輔助功能函數的重復性工作。文中示例將展示它相比于以前針對每…

如何在Windows上使用Docker搭建PHP開發環境

前言 在本地搭建開發環境我好像沒幾年就要折騰一次&#xff0c;因為本地開發電腦使用的是windows&#xff0c;早些年的時候&#xff0c;用過很多類似WAMP之類的東西&#xff0c;但最終都有或多或少不滿意的地方&#xff0c;前兩年的時候&#xff0c;還折騰過WSL&#xff0c;但…

批量文件名修改軟件:一鍵解決同一編碼多型號文件分類與命名難題,高效管理文件

在數字化時代&#xff0c;圖片文件已經成為我們工作中不可或缺的一部分。然而&#xff0c;當面對成百上千個同一編碼下不同型號的圖片文件時&#xff0c;如何快速、準確地進行分類和命名&#xff0c;成為了許多職場人士頭疼的問題。現在&#xff0c;我們為您帶來了一款神奇的批…

MyBatisPlus 基礎數據表的增刪改查 入門 簡單查詢

MyBatisPlus MyBatisPlus&#xff08;簡稱MP&#xff09;是一個基于MyBatis的增強工具庫&#xff0c;簡化了MyBatis的開發&#xff0c;提供了很多實用的功能和特性&#xff0c;如自動生成SQL、通用CRUD操作、分頁插件、條件構造器、代碼生成器等。它不僅簡化了開發過程&#x…

2024海亮日記

寫在前面&#xff1a;長文預警 20240617 聽說要去海亮&#xff0c;不考&#xff08;補考&#xff09;期末考試&#xff0c;于是進行一個停課的辦理&#xff0c;第一次進入410&#xff0c;被逆天的配置和氣氛所震驚 發誓這回去HL一定要有好效果&#xff0c;于是制定了詳細的計…

golang 未指定類型interface{} 類型的 int類型數據json.Unmarshal 解碼后變成float64類型問題解決方法

golang內置的json反序列化方法&#xff0c;默認情況下對應 未指定類型interface{} 類型的的 int類型數據在經過Unmarshal解碼后 int類型的數據會變成 float64類型。 因為json里面默認將interface{}類型的int數據都當做float64來處理。 解決方法很簡單&#xff0c;就是使用自定…

優盤有盤符顯示0字節:故障解析與數據恢復策略

一、優盤有盤符顯示0字節現象描述 在使用優盤的過程中&#xff0c;我們有時會遇到一種令人困惑的情況&#xff1a;插入優盤后&#xff0c;電腦能正常識別到優盤的盤符&#xff0c;但當我們嘗試訪問其中的數據時&#xff0c;卻發現優盤的容量顯示為0字節&#xff0c;無法讀取或…

快速掌握MyBatis

MyBatis 是一個流行的 Java 持久層框架&#xff0c;它提供了一種半自動的 SQL 映射方式&#xff0c;使得開發者能夠更加靈活地編寫 SQL 語句&#xff0c;同時避免了傳統 JDBC 代碼的冗余和復雜性。下面進行簡要概述&#xff1a; MyBatis 快速掌握 核心概念&#xff1a;理解 My…

8.1 Firmware Update Process

8.1 Firmware Update Process 通過reset激活firmware 更新的過程&#xff1a; host發出firmare下載命令&#xff0c;將FW image下載到控制器。FW image可能有多個部分要下載&#xff0c;因此FW image 下載命令中指定正在下載的FW image的每個部分的偏移量。FW image 下載命令…

Sui創始團隊在競速環節中的快問快答

在Sui Basecamp活動期間&#xff0c;Sui區塊鏈的最初貢獻者在Oracle紅牛賽車模擬器上展示了他們的技術能力&#xff0c;在駕駛圈時回答了有關Sui的問題。 Evan Cheng&#xff08;又名Revvin’ Evan&#xff09;在解釋Mysticeti創下區塊鏈最終性記錄的同時保持著他的駕駛線路。…

Java | Leetcode Java題解之第200題島嶼數量

題目&#xff1a; 題解&#xff1a; class Solution {void dfs(char[][] grid, int r, int c) {int nr grid.length;int nc grid[0].length;if (r < 0 || c < 0 || r > nr || c > nc || grid[r][c] 0) {return;}grid[r][c] 0;dfs(grid, r - 1, c);dfs(grid, r…

go Channel原理 (三)

Channel 設計原理 不要通過共享內存的方式進行通信&#xff0c;而是應該通過通信的方式共享內存。 在主流編程語言中&#xff0c;多個線程傳遞數據的方式一般都是共享內存。 Go 可以使用共享內存加互斥鎖進行通信&#xff0c;同時也提供了一種不同的并發模型&#xff0c;即通…

【嵌入式——FreeRTOS】任務

【嵌入式——FreeRTOS】任務 任務創建和刪除動態方式創建任務靜態方式創建任務 刪除任務任務切換調度器任務切換流程 任務掛起任務恢復相關API函數 任務創建和刪除 動態方式創建任務 任務的任務控制塊以及任務的棧空間所需的內存&#xff0c;均由freeRTOS從freeRTOS管理的堆中…

c#asp.net中字典的使用

字典是一個鍵值對&#xff0c;可以用來保存數據&#xff0c;再查詢&#xff1b; 下面是一個案例&#xff1a;依據多個學號查詢多個學生的姓名&#xff0c;只能到數據庫查詢一次數據&#xff01;&#xff01;&#xff01; 先在數據庫查詢學號對應的學生&#xff0c;把數據保存在…

mysql8.0.19安裝zip版本

下載地址https://downloads.mysql.com/archives/community/ 下載版本 下載后解壓&#xff0c;不包括data 和my.ini文件。其中data 文件是自動生成的【mysqld --initialize --console】&#xff0c;my.ini需要自己編寫設置。 新建my.ini文件 需要自己設置 basedirG:\soft\mysql…

內網服務器時間校正

新購買的云服務器發現內網機器和可以訪問外網的機器時間慢了三分鐘&#xff0c;導致有些訪問會報錯&#xff0c;那么我們配置一下ntp校正一下時間。外網配置起來比較簡單&#xff0c;直接下載ntp執行校正命令即可。 比當前時間慢了三分鐘 注意當前服務器是可以訪問外網的機器這…