Linux高級編程——線程

pthread 線程
? ?

?? ?概念 :線程是輕量級進程,一般是一個進程中的多個任務
? ? ? ? ? ? ? ? 進程是系統中最小的資源分配單位.
? ? ? ? ? ? ? ? 線程是系統中最小的執行單位。

? 優點: 比多進程節省資源,可以共享變量

進程會占用3g左右的空間,線程只會占用一部分,大概8M的空間

進程的父子不會共享,但一個進程之間的線程的資源可以共享.

進程的父子不是平級關系,線程是平級關系

?特征:s's
?? ?1、共享資源
?? ?2、效率高 ?30%
?? ?3、三方庫: pthread ?clone ? posix
?? ??? ??? ?3.1 編寫代碼頭文件: pthread.h
?? ??? ??? ?3.2 編譯代碼加載庫: -lpthread ? library?
?? ??? ??? ?libpthread.so? (linux庫)
?? ??? ??? ?gcc 1.c -lpthread? ? ?-lc
?? ?缺點:
?? ?1,線程和進程相比,穩定性,稍微差些
?? ?2,線程的調試gdb,相對麻煩些。
?? ??? ?info thread?
?? ??? ?*1 ?
?? ??? ?2?
?? ??? ?3
?? ??? ?thread 3?
?? ??? ?
線程與進程區別:

?? ?資源:
?? ??? ?線程比進程多了共享資源。 ?IPC
?? ??? ?線程又具有部分私有資源。
?? ??? ?進程間只有私有資源沒有共享資源。
?? ?空間:
?? ??? ?進程空間獨立,不能直接通信。
?? ??? ?線程可以共享空間,可以直接通信。

? ? ? ?進程解決相對復雜的問題,線 程解決相對復雜的問題.

共同點:

二者都可以并發

3、線程的設計框架 ?posix
?? ?

創建多線程 ==》線程空間操作 ===》線程資源回收
errno ? strerror(errno) ?perror();
??

?3.1 創建多線程:


?? ?int pthread_create(
?? ??? ?pthread_t *thread?,? const pthread_attr_t *attr,
?? ??? ?void *(*start_routine) (void *), void *arg);
?? ?功能:該函數可以創建指定的一個線程。
?? ?參數:thread 線程id,需要實現定義并由該函數返回。
?? ??? ? ?attr ? 線程屬性,一般是NULL,表示默認屬性。
?? ??? ? ?start_routine? ? ??指向指針函數的函數指針。
?? ??? ? ??? ??? ?本質上是一個函數的名稱即可。稱為
th?? ??? ??? ??? ?回調函數,是線程的執行空間。
{
}
?? ??? ? ?arg ?回調函數的參數,即參數3的指針函數參數。
?

?返回值:成功 0
? ? ? ? ? ? ? ? 失敗 錯誤碼

注意:一次pthread_create執行只能創建一個線程。
?? ? ?每個進程至少有一個線程稱為主線程。
?? ? ?主線程退出則所有創建的子線程都退出。暫時先用while(1);?
?? ? ?主線程必須有子線程同時運行才算多線程程序。
?? ? ?線程id是線程的唯一標識,是CPU維護的一組數字。
?? ? ?pstree 查看系統中多線程的對應關系。
?? ? ?多個子線程可以執行同一回調函數。
?? ?ps -eLf 查看線程相關信息Low Weigth Process
?? ?ps -eLo pid,ppid,lwp,stat,comm

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void *th1(void*arg)
{while(1){printf("發送視頻\n");sleep(1);}
}void *th2(void*arg)
{while(1){printf("接受控制\n");}
}int main(int argc, const char *argv[])
{pthread_t tid1,tid2;pthread_create(&tid1,NULL,th1,NULL);pthread_create(&tid2,NULL,th2,NULL);while(1);return 0;
}
  1. main?函數開始執行。
  2. 使用?pthread_create?創建了兩個線程?tid1?和?tid2
  3. th1?線程開始執行其無限循環,并在每次迭代中打印 "發送視頻",然后暫停一秒。
  4. 同時(幾乎是同時),th2?線程也開始執行其無限循環,不斷打印 "接受控制"。
  5. 因為兩個線程是并發執行的,所以它們之間沒有固定的打印順序。這取決于操作系統調度器的決策,哪個線程在何時獲得CPU時間片。
  6. main?函數中的?while(1);?是一個空循環,它使主線程保持活動狀態,防止程序立即退出。然而,這個空循環并沒有為程序提供任何有用的功能,通常你可能會使用某種形式的線程同步或等待(如?pthread_join)來確保主線程在所有其他線程完成后才退出。

此時輸出是亂的,是由于

  • 線程調度是由操作系統控制的,它決定哪個線程在何時運行。這取決于許多因素,包括線程優先級、系統負載、可用的CPU核心數量等。
  • 由于兩個線程都在無限循環中,并且沒有同步機制(如互斥鎖、條件變量等),所以它們會盡可能快地交替執行(或并行執行,如果系統有多個CPU核心),導致輸出看起來沒有規律。

2、pthread_t pthread_self(void); unsigned long int; %lu? 獲取線程號


? ?功能:獲取當前線程的線程id
? ?參數:無
? ?返回值:成功 返回當前線程的線程id
? ??? ??? ??? ?失敗 ?-1;
?? ??? ??? ?syscall(SYS_gettid);
這個方法重啟后失效
alias gcc='gcc -g -pthread '
unalias gcc?

永久起作用
cd ~ //家目錄
vim .bashrc
alias gcc='gcc -g -pthread ' ?:wq

source .bashrc ?生效

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void *th1 (void*arg)
{while(1){printf("發送視頻 %lu\n",pthread_self());sleep(1);}
}void *th2 (void*arg)
{while(1){printf("接受控制 %lu\n",pthread_self());sleep(1);}
}int main(int argc, char *argv[])
{pthread_t tid1,tid2;pthread_create(&tid1,NULL,th1,NULL);pthread_create(&tid2,NULL,th2,NULL);printf("main th %lu\n",pthread_self());while(1);return 0;
}
  • 使用pthread_create創建兩個線程:tid1(運行th1)和tid2(運行th2)。
  • 打印主線程的ID。
  • 使用while(1);使主線程進入無限循環,以保持程序運行。否則,當主線程結束時,程序可能會立即終止,導致其他線程也被終止

練習題:
?? ?設計一個多線程程序,至少有三個子線程
?? ?每個線程執行不同的任務,并實時打印執行
?? ?過程,同時表明身份。

?? ?eg: ./a.out ?==>tid =xxx... ?zheng ...
?? ??? ??? ??? ??? ?tid2 = xxx wozai.
?? ??? ??? ??? ??? ?tid3 = xxx ?wozai ssss


線程的退出:

1.直接用return;? ?

2: 自行退出 ==》自殺 ?==》子線程自己退出
?? ??? ?exit(1);
?? ??? ?void pthread_exit(void *retval); ?exit ?return p;
?? ??? ?功能:子線程自行退出
?? ??? ?參數: retval 線程退出時候的返回狀態,臨死遺言。
?? ??? ?返回值:無

?? ??? ??? ?th
?? ??? ??? ?{
?? ??? ??? ??? ?int a =10;

?? ??? ??? ??? ?pthread_exit(&a);
?? ??? ??? ?}
?? ??? ??? ?join(,&ret)


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void *th1 (void*arg)
{int i =10;while(i--){printf("發送視頻 %lu\n",pthread_self());sleep(1);}pthread_exit(NULL);//return NULL;
}void *th2 (void*arg)
{int i = 10;while(i--){printf("接受控制 %lu\n",pthread_self());sleep(1);}pthread_exit(NULL);
}int main(int argc, char *argv[])
{pthread_t tid1,tid2;pthread_create(&tid1,NULL,th1,NULL);pthread_create(&tid2,NULL,th2,NULL);printf("main th %lu\n",pthread_self());while(1);return 0;
}


? ? 3.?強制退出 ==》他殺 ?==》主線程結束子線程
?? ??? ?int pthread_cancel(pthread_t thread);
?? ??? ?功能:請求結束一個線程? (在主線程種調用 寫入某個線程id號,可以關閉該線程)
?? ??? ?參數:thread 請求結束一個線程tid(想要關閉的線程id號)
?? ??? ?返回值:成功 0
?? ??? ??? ??? ?失敗 -1;

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void *th1 (void*arg)
{while(1){printf("發送視頻\n");sleep(1);}
}void *th2 (void*arg)
{while(1){printf("接受控制\n");sleep(1);}
}int main(int argc, char *argv[])
{pthread_t tid1,tid2;pthread_create(&tid1,NULL,th1,NULL);pthread_create(&tid2,NULL,th2,NULL);int i = 0 ;while(1){i++;if(3 == i ){pthread_cancel(tid1);}if(5 ==i){pthread_cancel(tid2);}sleep(1);}return 0;
}

作業:
?? ?創建一個多線程程序,至少有10個子線程,
?? ?每個線程有會打印不同的數據,同時表明身份。

?? ?
?? ?線程的回收


?? ?1、線程的回收機制 ====》不同與進程沒有孤兒線程和僵尸線程。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??====》主線程結束任意生成的子線程都會結束。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ====》?子線程的結束不會影響主線程的運行。
?? ?char * retval ; retval++; 1?
?? ?int * retval;?

? ? int pthread_join(pthread_t thread, void **retval); ? ?
? 功能:通過該函數可以將指定的線程資源回收,該函數具有阻塞等待功能,如果指定的線程沒有結束,則回收線程會阻塞。
? 參數:thread ?要回收的子線程tid
? ? ? ? ? ? ??retval ?要回收的子線程返回值/狀態。==》ptread_exit(值);
? 返回值:成功 0
? ? ? ? ? ? ? ? ?失敗 返回一個錯誤號,是一個大于零的數;

? ? ? ? ? ? ? ? ? 失敗可以用

? ? ? ? ? ? ? ?

?

#include <unistd.h>
#include <string.h>
#include <pthread.h>
void *th1 (void*arg)
{int i = 10;while(i--){printf("發送視頻\n");sleep(1);}
}void *th2 (void*arg)
{int i = 10;while(i--){printf("接受控制\n");sleep(1);}
}int main(int argc, char *argv[])
{pthread_t tid1,tid2;pthread_create(&tid1,NULL,th1,NULL);int ret = pthread_create(&tid2,NULL,th2,NULL);if(ret!=0){// perror()fprintf(stderr,"error %s\n",strerror(ret));//exit();}pthread_join(tid1,NULL);pthread_join(tid2,NULL);return 0;
}

子線程的回收策略:
? 1、如果預估子線程可以有限范圍內結束則正常用pthread_join等待回收。
? 2、如果預估子線程可能休眠或者阻塞則等待一定時間后強制回收。
? 3、如果子線程已知必須長時間運行則,不再回收其資源。
??
??


? 線程的參數,返回值
??

1、傳參數
?? ??? ?
?? ?傳整數 ===》int add(int a,int b); ?///a b 形參
?? ??? ??? ??? ?add(x,y); ? ?x y 實參?

?? ??? ?pthread_create(&tid,NULL,fun,x);

?? ??? ?fun ==>void * fun(void * arg);
?? ??? ?
?? ?練習:創建一個子線程并向該線程中傳入一個字符在
?? ??? ? ?線程中打印輸出。
?? ??? ? ?在此基礎上向子線程中傳入一個字符串,并在
?? ??? ? ?子線程中打印輸出。

?? ??? ? ?
?? ??? ? ?add(int a, int b)
?? ??? ? ?{
?? ??? ??? ?int c = a+b;
?? ??? ??? ?char buf[]=""
?? ??? ??? ?return c;
?? ??? ? ?}
?? ??? ??? ??? ??? ?5
?? ??? ? ?int d = add(2,3);

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>void* th(void* arg)
{static int a =20;return &a;
}int main(int argc, char *argv[])
{pthread_t tid;void* ret;pthread_create(&tid,NULL,th,NULL);pthread_join(tid,&ret);printf("ret %d\n",*(int*)ret);return 0;
}


?? ?傳字符串
?? ??? ?棧區字符數組:
?? ??? ?字符串常量:
?? ??? ?char *p = "hello";
?? ??? ?堆區字符串;
?? ??? ??? ?char *pc = (char *)malloc(128);
?? ??? ??? ?ptread_create(&tid,NULL,fun,pc);

?? ??? ??? ?pthread_join(tid,NULL);

?? ??? ??? ?free(pc);
?? ??? ?
?? ??? ??? ?fun(void *arg)
?? ??? ??? ?{
?? ??? ??? ??? ?char * pc = (char *)arg?? ?;
?? ??? ??? ??? ?printf("%s \n",pc);
?? ??? ??? ??? ??? ??? ?%c
?? ??? ??? ?}

棧區

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>void* th(void* arg)
{static char buf[256]={0};strcpy(buf,"要消亡了\n");return buf;
}int main(int argc, char *argv[])
{pthread_t tid;void* ret;pthread_create(&tid,NULL,th,NULL);pthread_join(tid,&ret);printf("ret %s\n",(char*)ret);return 0;
}

堆區:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>void* th(void* arg)
{char * tmp = (char* )arg;strcpy(tmp,"hello");return tmp;
}int main(int argc, char *argv[])
{pthread_t tid;char * p = (char*)malloc(50);void* ret;pthread_create(&tid,NULL,th,p);pthread_join(tid,&ret);printf("ret %s\n",(char*)ret);free(p);return 0;
}

??

?傳結構體
?? ?1、定義結構體類型
?? ?2、用結構體定義變量
?? ?3、向pthread_create傳結構體變量
?? ?4、從fun子線程中獲取結構體數據

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
typedef struct 
{char * p;int a;
}TH_ARG;
void* th(void* arg)
{TH_ARG * tmp = (TH_ARG* )arg;strcpy(tmp->p,"hello");//strcpy( ((TH_ARG*)arg)->p ,"hello");tmp->a +=10;return tmp;
}int main(int argc, char *argv[])
{pthread_t tid;int a  =20;char * p = (char*)malloc(50);TH_ARG arg;arg.a = a;arg.p = p;void* ret;pthread_create(&tid,NULL,th,&arg);pthread_join(tid,&ret);printf("ret %s %d\n",((TH_ARG*)ret)->p,((TH_ARG*)ret)->a);free(p);return 0;
}

練習:
?? ?定義一個包含不同數據類型的測試結構體
?? ?并向子線程傳參數,同時在子線程中打印輸出。


?? ?定義一個回調函數可以完成計算器的功能
?? ?定義一個數據結構體可以一次傳入不同的數據
?? ?和計算方式并將結果打印輸出。
?? ?//2 + 3.6?
?? ?// 2 + 3 ?2+3
?? ?// 8 * 6
?? ?typedef strcut
?? ?{
?? ??? ?float a;
?? ??? ?float b;
?? ??? ?char c;//+ - * /?
?? ??? ?float d;
?? ?}JSQ;
?? ?
?? ?

返回值:pthread_exit(0) ===>pthread_exit(9);
?? ??? ?pthread_join(tid,NULL); ===>pthread_join(tid,?);
10;
-10;
int * p =malloc(4);
*p = -10;
1、pthread_exit(?) ==>? = void * retval;
?? ??? ??? ??? ??? ??? ? ?純地址

2、pthread_join(tid,?) ==>? = void **retval;
?? ??? ??? ??? ??? ??? ??? ?地址的地址
原理:子線程退出的時候,可以返回一個內存地址
?? ? ?改值所在的內存中可以存儲任何數據,只要
?? ? ?地址存在,則數據都可以正常返回。
?? ?
?? ?地址有三種:
?? ?0、棧區變量 ?錯誤,子線程結束該地址失效。
?? ?1、全局變量 ?失去意義,本質可以直接訪問。

?? ?2、靜態變量?
?? ?3、堆區變量


?? ? ?主線程通過一個地址形式的變量來接受子進程
?? ? ?返回的地址變量就可以將該地址中的數據取到。

?? ?練習:從子線程中申請一塊堆區內存并存字符串
? ? ? 將該字符串以返回值形式返回到主線程并打印輸出。
?? ? ??? ?
?

? ?設置分離屬性,目的線程消亡,自動回收空間。
??

主線程沒有空,才設置分離屬性來回收.

?attribute

?int pthread_attr_init(pthread_attr_t *attr);
?? ?功能,初始化一個attr的變量
?? ?參數:attr,需要變量來接受初始值
?? ?返回:0 ?成功,
?? ?非0 錯誤;
? ? ? ?int pthread_attr_destroy(pthread_attr_t *attr);
?? ? ?功能:銷毀attr變量。
?? ? ?attr,屬性變量
?? ? ?返回:0 ?成功,
?? ?非0 錯誤;
?? ? ??
?? ? ??
?? ?man -k?
?? ? int pthread_attr_setdetachstate(pthread_attr_t *attr
, int detachstate);

?? ?功能:把一個線程設置成相應的屬性
?? ?參數,attr,屬性變量,有init函數初始化他。
?? ?detachstate:有2個可選值,
?? ?
?? ?PTHREAD_CREATE_DETACHED:設置分離屬性。
?? ?
?? ?第二種設置分離屬性:
int pthread_deatch(pthread_t thread);
?? ?功能,設置分離屬性
?? ?參數,線程id號,填自己的id
?? ?
?? ?do{
?? ?
?? ?
?? ?}while()

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
void* th(void* arg)
{pthread_detach(pthread_self());return NULL;
}int main(int argc, char *argv[])
{pthread_t tid;int i = 0 ;for(i=0;i<50000;i++){int ret = pthread_create(&tid,NULL,th,NULL);if(ret!=0){break;}// pthread_detach(tid);}printf("%d \n",i);return 0;
}


void pthread_cleanup_push(void (*routine)(void *), void *arg);

?? ?功能:注冊一個線程清理函數
?? ?參數,routine,線程清理函數的入口
?? ??? ?arg,清理函數的參數。
?? ?返回值,無
?? ??? ?
void pthread_cleanup_pop(int execute);
?? ?功能:調用清理函數
?? ?execute,非0 ?執行清理函數
?? ??? ??? ?0 ,不執行清理
?? ??? ??? ?
?? ?返回值,無

do
{

}while(1)

process?? ??? ??? ??? ?thread
fork?? ??? ??? ??? ?pthread_create?
getpid,ppid,?? ??? ?pthread_self
exit,?? ??? ??? ??? ?pthread_exit?
wait,waitpid,?? ??? ?pthread_join?
kill,?? ??? ??? ??? ?pthread_cancel
atexit ?? ??? ??? ??? ?pthread_clean,
exec?? ??? ??? ??? ?system--->fork->exec (ls)
?? ??? ??? ??? ??? ?
?

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

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

相關文章

【高考】選專業時,應避免的誤區

【高考】選專業時&#xff0c;應避免的誤區-CSDN博客 【高考】選專業時以什么為主&#xff1f;-CSDN博客 分數限制下&#xff0c;選好專業還是選好學校&#xff1f;-CSDN博客 分數限制下&#xff0c;選好專業還是選好學校&#xff1f;-CSDN博客 在選專業時&#xff0c;考生…

解析 ThreadLocal 原理

ThreadLocal用于線程局部變量的一個工具類。 原理是為每個線程創建獨立的變量副本&#xff0c;從而實現線程數據的隔離。具體來說&#xff0c;ThreadLocal 通過一個 ThreadLocalMap來實現&#xff0c;這個 ThreadLocalMap 是一個自定義的哈希表&#xff0c;用于存儲線程和對應的…

Qt creator實現一個簡單計算器

目錄 1 界面設計 2 思路簡介 3 代碼 目錄 1 界面設計 ?2 思路簡介 3 代碼 3.1 widget.h 3.2 widget.c 4 完整代碼 在這里主要記載了如何使用Qt creator完成一個計算器的功能。該計算器可以實現正常的加減乘除以及括號操作&#xff0c;能實現簡單的計算器功能。 1 界…

Hadoop版本演變、分布式集群搭建

Hadoop版本演變歷史 Hadoop發行版非常的多&#xff0c;有華為發行版、Intel發行版、Cloudera Hadoop(CDH)、Hortonworks Hadoop(HDP)&#xff0c;這些發行版都是基于Apache Hadoop衍生出來的。 目前Hadoop經歷了三個大的版本。 hadoop1.x&#xff1a;HDFSMapReduce hadoop2.x…

MySQL學習_python操作MySQL

用python連接數據庫分為以下幾個步驟 1.首先下載pymysql pip install pymysql2.創建數據 # 1.導入pymysql import pymysql # 2.連接MySQL conn pymysql.connect(host127.0.0.1,port3306,userroot,charsetutf8,dbunicom) cursor conn.cursor(cursorpymysql.cursors.DicCurso…

uniapp開發企業微信內部應用

最近一直忙著開發項目&#xff0c;終于1.0版本開發完成&#xff0c;抽時間自己總結下在項目開發中遇到的技術點。此次項目屬于自研產品&#xff0c;公司擴展業務&#xff0c;需要在企業微信中開發內部應用。因為工作中使用的是釘釘&#xff0c;很少使用企業微信&#xff0c;對于…

重新記錄做事的方向和內容(2024年6月28日19:50:38)

感覺自己沒必要這么焦慮&#xff0c;最后的結果無非就是自己又開始恢復到自己抽煙&#xff0c;喝酒&#xff0c;說臟話的一個狀態&#xff0c;自己那么糟糕自己都已經通過實事求是走出來了&#xff0c;現在難道自己還害怕什么&#xff1f; 如果順著這種封閉和沒有斷舍離的狀態…

【Qt C++實現繪制儀表盤】

要在Qt C中繪制儀表盤&#xff0c;您可以使用QChart、QSeries、QBarSeries、QPointSeries等類。以下是一個簡單的示例&#xff0c;演示如何使用這些類創建一個繪圖儀表盤&#xff1a; #include <QApplication> #include <QChart> #include <QChartView> #in…

06 Shell編程實戰——案例1

腳本編程步驟&#xff1a; 腳本編程一般分為4個步驟&#xff0c;即先確定需求&#xff0c;然后再確定你所要用到的語句&#xff0c; 需求分析&#xff1a;根據系統管理的需求&#xff0c;分析腳本要實現的功能、功能實現的層次、實現的命令與語句等&#xff1b;命令測試&…

Windows11下安裝多個JDK版本,并切換

Windows11下安裝多個JDK版本,并切換 前言步驟1、前期準備2、版本切換思考前言 一臺電腦可以同時安裝多個版本 jdk,建議兩個,最多不超三個。安裝多個JDK版本可能會占用較多的磁盤空間。此外,同時運行多個 JDK 版本可能會對系統性能產生一定的影響。 ??切換 JDK 有兩種方式…

ios swift5 視頻播放 播放視頻失敗 無法播放HEVC (H.265) 格式的視頻 H.264格式的可以播放

文章目錄 1.問題2.原因&#xff1a;iOS swift AVPlayerViewController無法播放HEVC (H.265) 格式的視頻3.解決方法用第三方框架MobileVLCKit來播放4.用MobileVLCKit寫的播放器4.1 兩個oc版本的4.2 兩個swiftUI版本的5.蘋果是支持HEVC (H.265) 格式的視頻&#xff0c;是硬件那邊…

css做旋轉星球可舉一反三

<!DOCTYPE html> <html lang"en"><head> <meta charset"UTF-8" /> <title>旋轉的星球</title> <style type"text/css">.box {/*position: relative;*/position: absolute;width: 139px;height: 139p…

計算文本相似度的幾種方法

計算文本相似度的幾種方法 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們來探討一下計算文本相似度的幾種方法。文本相似度在自然語言處理&#xff08…

算法訓練 | 動態規劃Part10 | 300.最長遞增子序列、674.最長連續遞增序列、718.最長重復子數組

目錄 300.最長遞增子序列 動態規劃法 674.最長連續遞增序列 動態規劃法 718.最長重復子數組 動態規劃法 300.最長遞增子序列 題目鏈接&#xff1a;300. 最長遞增子序列 - 力扣&#xff08;LeetCode&#xff09; 文章講解&#xff1a;代碼隨想錄 動態規劃法 “子序列是…

基于java語言+springboot技術架構開發的 互聯網智能3D導診系統源碼支持微信小程序、APP 醫院AI智能導診系統源碼

基于java語言springboot技術架構開發的 互聯網智能3D導診系統源碼支持微信小程序、APP 醫院AI智能導診系統源碼 一、智慧導診系統開發原理 導診系統從原理上大致可分為基于規則模板和基于數據模型兩類。 1、基于規則推理的方法通過人工建立癥狀、疾病和科室之間的對應規則實現…

Java反射API詳解與應用場景

一、Java反射API簡介: 一、什么是反射: 反射是一種強大的工具,它允許我們在運行時檢查類、方法和字段的信息,甚至允許我們動態的調用特定類的方法或改變字段的值。編程語言中的反射機制通常用于從類、對象或方法中檢索元數據,或者更特別的說,從代碼本身中獲取信息。這就…

【51單片機入門】點亮數碼管

文章目錄 前言仿真圖如何去繪制一個數字示例代碼選擇某個數碼管顯示某個數字 示例代碼總結 前言 在嵌入式系統的世界中&#xff0c;單片機扮演著至關重要的角色。51單片機&#xff0c;作為最早的微控制器之一&#xff0c;至今仍被廣泛應用在各種設備中。本文將介紹如何使用51單…

幾種linux開機自啟腳本的方法

幾種linux開機自啟腳本的方法 1. 腳本添加到init.d目錄中2. 創建服務service&#xff08;推薦&#xff09;3. /etc/profile & /etc/profile.d&#xff08;不推薦&#xff09;4. /etc/rc.local 本文以啟動jenkins節點為例&#xff0c;需要持久連接&#xff0c;實現開機自啟 …

js或ts中對象如何循環遍歷獲取名字和值

數組循環有多種方法&#xff0c;但是對象循環還是會遇到一些問題 分開獲取key或value let names{name:kaka,age:12}獲取key值代碼&#xff1a; Object.keys(names).forEach(name>{console.log(name) })結果&#xff1a; 獲取value值代碼&#xff1a; Object.values(name…

多地高溫持續“熱力”爆表 約克VRF中央空調帶你清涼舒爽一夏

“出門5分鐘&#xff0c;流汗2小時”,夏季高溫天氣&#xff0c;怎一個“熱”字了得&#xff1f;6月以來&#xff0c;我國多地迎來高溫“炙烤”&#xff0c;全國出現40℃以上高溫的范圍持續增加&#xff0c;隨著中央氣象臺高溫預警持續拉響&#xff0c;人們都很納悶&#xff1a;…