Linux 內核中斷內幕【轉】

轉自:http://www.ibm.com/developerworks/cn/linux/l-cn-linuxkernelint/

本文對中斷系統進行了全面的分析與探討,主要包括中斷控制器、中斷分類、中斷親和力、中斷線程化與 SMP 中的中斷遷徙等。首先對中斷工作原理進行了簡要分析,接著詳細探討了中斷親和力的實現原理,最后對中斷線程化與非線程化中斷之間的實現機理進行了對比分析。

3?評論:

蘇 春艷, 在讀研究生

楊 小華?(normalnotebook@126.com), 在讀研究生

2007 年 5 月 14 日

  • expand內容

什么是中斷

Linux 內核需要對連接到計算機上的所有硬件設備進行管理,毫無疑問這是它的份內事。如果要管理這些設備,首先得和它們互相通信才行,一般有兩種方案可實現這種功能:

  1. 輪詢(polling?讓內核定期對設備的狀態進行查詢,然后做出相應的處理;
  2. 中斷(interrupt?讓硬件在需要的時候向內核發出信號(變內核主動為硬件主動)。

第一種方案會讓內核做不少的無用功,因為輪詢總會周期性的重復執行,大量地耗用 CPU 時間,因此效率及其低下,所以一般都是采用第二種方案 。注釋 1

從物理學的角度看,中斷是一種電信號,由硬件設備產生,并直接送入中斷控制器(如 8259A)的輸入引腳上,然后再由中斷控制器向處理器發送相應的信號。處理器一經檢測到該信號,便中斷自己當前正在處理的工作,轉而去處理中斷。此后,處理器會通知 OS 已經產生中斷。這樣,OS 就可以對這個中斷進行適當的處理。不同的設備對應的中斷不同,而每個中斷都通過一個唯一的數字標識,這些值通常被稱為中斷請求線。

回頁首

APIC vs 8259A

X86計算機的 CPU 為中斷只提供了兩條外接引腳:NMI 和 INTR。其中 NMI 是不可屏蔽中斷,它通常用于電源掉電和物理存儲器奇偶校驗;INTR是可屏蔽中斷,可以通過設置中斷屏蔽位來進行中斷屏蔽,它主要用于接受外部硬件的中斷信號,這些信號由中斷控制器傳遞給 CPU。

常見的中斷控制器有兩種:

1. 可編程中斷控制器8259A

傳統的 PIC(Programmable Interrupt Controller)是由兩片 8259A 風格的外部芯片以“級聯”的方式連接在一起。每個芯片可處理多達 8 個不同的 IRQ。因為從 PIC 的 INT 輸出線連接到主 PIC 的 IRQ2 引腳,所以可用 IRQ 線的個數達到 15 個,如圖 1 所示。

圖 1:8259A 級聯原理圖
8259A 級聯原理圖

2. 高級可編程中斷控制器(APIC)

8259A 只適合單 CPU 的情況,為了充分挖掘 SMP 體系結構的并行性,能夠把中斷傳遞給系統中的每個 CPU 至關重要。基于此理由,Intel 引入了一種名為 I/O 高級可編程控制器的新組件,來替代老式的 8259A 可編程中斷控制器。該組件包含兩大組成部分:一是“本地 APIC”,主要負責傳遞中斷信號到指定的處理器;舉例來說,一臺具有三個處理器的機器,則它必須相對的要有三個本地 APIC。另外一個重要的部分是 I/O APIC,主要是收集來自 I/O 裝置的 Interrupt 信號且在當那些裝置需要中斷時發送信號到本地 APIC,系統中最多可擁有 8 個 I/O APIC。

每個本地 APIC 都有 32 位的寄存器,一個內部時鐘,一個本地定時設備以及為本地中斷保留的兩條額外的 IRQ 線 LINT0 和 LINT1。所有本地 APIC 都連接到 I/O APIC,形成一個多級 APIC 系統,如圖 2 所示。

圖 2:多級I/O APIC系統
多級I/O APIC系統

目前大部分單處理器系統都包含一個 I/O APIC 芯片,可以通過以下兩種方式來對這種芯片進行配置:

1) 作為一種標準的 8259A 工作方式。本地 APIC 被禁止,外部 I/O APIC 連接到 CPU,兩條 LINT0 和 LINT1 分別連接到 INTR 和 NMI 引腳。

2) 作為一種標準外部 I/O APIC。本地 APIC 被激活,且所有的外部中斷都通過 I/O APIC 接收。

辨別一個系統是否正在使用 I/O APIC,可以在命令行輸入如下命令:

# cat /proc/interruptsCPU0       0:      90504    IO-APIC-edge  timer1:        131    IO-APIC-edge  i80428:          4    IO-APIC-edge  rtc9:          0    IO-APIC-level  acpi12:        111    IO-APIC-edge  i804214:       1862    IO-APIC-edge  ide015:         28    IO-APIC-edge  ide1
177:          9    IO-APIC-level  eth0
185:          0    IO-APIC-level  via82cxxx
...

如果輸出結果中列出了 IO-APIC,說明您的系統正在使用 APIC。如果看到 XT-PIC,意味著您的系統正在使用 8259A 芯片。

回頁首

中斷分類

中斷可分為同步(synchronous)中斷和異步(asynchronous)中斷:

1. 同步中斷是當指令執行時由 CPU 控制單元產生,之所以稱為同步,是因為只有在一條指令執行完畢后 CPU 才會發出中斷,而不是發生在代碼指令執行期間,比如系統調用。

2. 異步中斷是指由其他硬件設備依照 CPU 時鐘信號隨機產生,即意味著中斷能夠在指令之間發生,例如鍵盤中斷。

根據 Intel 官方資料,同步中斷稱為異常(exception),異步中斷被稱為中斷(interrupt)。

中斷可分為可屏蔽中斷(Maskable interrupt)和非屏蔽中斷(Nomaskable interrupt)。異常可分為故障(fault)、陷阱(trap)、終止(abort)三類。

從廣義上講,中斷可分為四類:中斷故障陷阱終止。這些類別之間的異同點請參看 表 1。

類別原因異步/同步返回行為
中斷來自I/O設備的信號異步總是返回到下一條指令
陷阱有意的異常同步總是返回到下一條指令
故障潛在可恢復的錯誤同步返回到當前指令
終止不可恢復的錯誤同步不會返回

X86 體系結構的每個中斷都被賦予一個唯一的編號或者向量(8 位無符號整數)。非屏蔽中斷和異常向量是固定的,而可屏蔽中斷向量可以通過對中斷控制器的編程來改變。

回頁首

Linux 2.6 中斷處理原理簡介

中斷描述符表(Interrupt Descriptor Table,IDT)是一個系統表,它與每一個中斷或異常向量相聯系,每一個向量在表中存放的是相應的中斷或異常處理程序的入口地址。內核在允許中斷發生前,也就是在系統初始化時,必須把 IDT 表的初始化地址裝載到 idtr 寄存器中,初始化表中的每一項。

當處于實模式下時,IDT 被初始化并由 BIOS 程序所使用。然而,一旦 Linux 開始接管,IDT 就被移到 ARM 的另一個區域,并進行第二次初始化,因為 Linux 不使用任何 BIOS 程序,而使用自己專門的中斷服務程序(例程)(interrupt service routine,ISR)。中斷和異常處理程序很像常規的 C 函數

有三個主要的數據結構包含了與 IRQ 相關的所有信息:hw_interrupt_typeirq_desc_t?和?irqaction,圖3 解釋了它們之間是如何關聯的。

圖 3:IRQ 結構之間的關系
IRQ結構之間的關系

在 X86 系統中,對于 8259A 和 I/O APIC 這兩種不同類型的中斷控制器,hw_interrupt_type?結構體被賦予不同的值,具體區別參見表 2。

8259AI/O APIC
static struct hw_interrupt_type i8259A_irq_type = { "XT-PIC", startup_8259A_irq, shutdown_8259A_irq, enable_8259A_irq, disable_8259A_irq, mask_and_ack_8259A, end_8259A_irq, NULL };static struct hw_interrupt_type ioapic_edge_type = { .typename = "IO-APIC-edge", .startup = startup_edge_ioapic, .shutdown = shutdown_edge_ioapic, .enable = enable_edge_ioapic, .disable = disable_edge_ioapic, .ack = ack_edge_ioapic, .end = end_edge_ioapic, .set_affinity = set_ioapic_affinity, }; static struct hw_interrupt_type ioapic_level_type = { .typename = "IO-APIC-level", .startup = startup_level_ioapic, .shutdown = shutdown_level_ioapic, .enable = enable_level_ioapic, .disable = disable_level_ioapic, .ack = mask_and_ack_level_ioapic, .end = end_level_ioapic, .set_affinity = set_ioapic_affinity, };

在中斷初始化階段,調用?hw_interrupt_type?類型的變量初始化?irq_desc_t?結構中的?handle?成員。在早期的系統中使用級聯的8259A,所以將用?i8259A_irq_type?來進行初始化,而對于SMP系統來說,要么以?ioapic_edge_type,或以?ioapic_level_type?來初始化?handle?變量。

對于每一個外設,要么以靜態(聲明為?static?類型的全局變量)或動態(調用?request_irq?函數)的方式向 Linux 內核注冊中斷處理程序。不管以何種方式注冊,都會聲明或分配一塊?irqaction?結構(其中?handler?指向中斷服務程序),然后調用?setup_irq()?函數,將irq_desc_t?和?irqaction?聯系起來。

當中斷發生時,通過中斷描述符表 IDT 獲取中斷服務程序入口地址,對于?32≤ i ≤255(i≠128)?之間的中斷向量,將會執行?push $i-256,jmp common_interrupt?指令。隨之將調用?do_IRQ()?函數,以中斷向量為?irq_desc[]?結構的下標,獲取?action?的指針,然后調用handler?所指向的中斷服務程序。

從以上描述,我們不難看出整個中斷的流程,如圖 4 所示:

圖 4:X86中斷流
X86中斷流

本文作者之一曾經對2.6.10的中斷系統進行過情景分析,有興趣的讀者可以和作者取得聯系,獲取相關資料。

回頁首

中斷綁定——中斷親和力(IRQ Affinity)

在 SMP 體系結構中,我們可以通過調用系統調用和一組相關的宏來設置 CPU 親和力(CPU affinity),將一個或多個進程綁定到一個或多個處理器上運行。中斷在這方面也毫不示弱,也具有相同的特性。中斷親和力是指將一個或多個中斷源綁定到特定的 CPU 上運行。中斷親和力最初由 Ingo Molnar 設計并實現。

在?/proc/irq?目錄中,對于已經注冊中斷處理程序的硬件設備,都會在該目錄下存在一個以該中斷號命名的目錄?IRQ#?,IRQ#?目錄下有一個smp_affinity?文件(SMP 體系結構才有該文件),它是一個 CPU 的位掩碼,可以用來設置該中斷的親和力, 默認值為?0xffffffff,表明把中斷發送到所有的 CPU 上去處理。如果中斷控制器不支持?IRQ affinity,不能改變此默認值,同時也不能關閉所有的 CPU 位掩碼,即不能設置成?0x0

我們以網卡(eth1,中斷號 44 )為例,在具有 8 個 CPU 的服務器上來設置網卡中斷的親和力(以下數據出自內核源碼?Documentation\IRQ-affinity.txt):

[root@moon 44]# cat smp_affinity
ffffffff
[root@moon 44]# echo 0f > smp_affinity
[root@moon 44]# cat smp_affinity
0000000f
[root@moon 44]# ping -f h
PING hell (195.4.7.3): 56 data bytes
...
--- hell ping statistics ---
6029 packets transmitted, 6027 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.1/0.4 ms
[root@moon 44]# cat /proc/interrupts | grep 44:44:   0   1785   1785   1783   1783   1   1   0   IO-APIC-level   eth1
[root@moon 44]# echo f0 > smp_affinity
[root@moon 44]# ping -f h
PING hell (195.4.7.3): 56 data bytes
..
--- hell ping statistics ---
2779 packets transmitted, 2777 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.5/585.4 ms
[root@moon 44]# cat /proc/interrupts | grep 44:44:  1068  1785  1785  1784   1784   1069   1070   1069   IO-APIC-level  eth1
[root@moon 44]#

在上例中,我們首先只允許在 CPU0~3 上處理網卡中斷,接著運行 ping 程序,不難發現在 CPU4~7 上并沒有對網卡中斷進行處理。然后只在 CPU4~7 上對網卡中斷進行處理, CPU0~3 不對網卡中斷進行任何處理,運行 ping 程序之后,再次查看?/proc/interrupts?文件時,不難發現 CPU4~7 上的中斷次數明顯增加,而 CPU0~3 上的中斷次數沒有太大的變化。

在探討中斷親和力的實現原理之前,我們首先來了解 I/O APIC 中的組成。

I/O APIC 由一組 24 條 IRQ 線,一張 24 項的中斷重定向表(Interrupt Redirection Table),可編程寄存器,以及通過 APIC 總線發送和接收 APIC 信息的一個信息單元組成。其中與中斷親和力息息相關的是中斷重定向表,中斷重定向表表中的每一項都可以被單獨編程以指明中斷向量和優先級、目標處理器及選擇處理器的方式

通過表 2,不難發現 8259A 和 APIC 中斷控制器最大不同點在于?hw_interrupt_type?類型變量的最后一項。對于 8259A 類型,set_affinity被置為?NULL,而對于 SMP 的 APIC 類型,set_affinity?被賦值為?set_ioapic_affinity

在系統初始化期間,對于 SMP 體系結構,將會調用?setup_IO_APIC_irqs()?函數來初始化 I/O APIC 芯片,芯片中的中斷重定向表的 24 項被填充。在系統啟動期間,所有的 CPU 都執行?setup_local_APIC()?函數,完成本地的 APIC 初始化。當有中斷被觸發時,將相應的中斷重定向表中的值轉換成一條消息,然后,通過 APIC 總線把消息發送給一個或多個本地 APIC 單元,這樣,中斷就能立即被傳遞給一個特定的 CPU,或一組 CPU,或所有的 CPU,從而來實現中斷親和力。

當我們通過 cat 命令將 CPU 掩碼寫進?smp_affinity?文件時,此時的調用路線圖為:write()?->sys_write()?->vfs_write()?->proc_file_write()?->irq_affinity_write_proc()?->set_affinity()?->set_ioapic_affinity()?->set_ioapic_affinity_irq()?->io_apic_write();其中在調用?set_ioapic_affinity_irq()?函數時,以中斷號和 CPU 掩碼作為參數,接著繼續調用?io_apic_write(),修改相應的中斷重定向中的值,來完成中斷親和力的設置。當執行 ping 命令時,網卡中斷被觸發,產生了一個中斷信號,多 APIC 系統根據中斷重定向表中的值,依照仲裁機制,選擇 CPU0~3 中的某一個 CPU,并將該信號傳遞給相應的本地 APIC,本地 APIC 又中斷它的 CPU,整個事件不通報給其他所有的 CPU。

回頁首

新特性展望——中斷線程化(Interrupt Threads)

在嵌入式領域,業界對 Linux 實時性的呼聲越來越高,對中斷進行改造勢在必行。在 Linux 中,中斷具有最高的優先級。不論在任何時刻,只要產生中斷事件,內核將立即執行相應的中斷處理程序,等到所有掛起的中斷和軟中斷處理完畢后才能執行正常的任務,因此有可能造成實時任務得不到及時的處理。中斷線程化之后,中斷將作為內核線程運行而且被賦予不同的實時優先級,實時任務可以有比中斷線程更高的優先級。這樣,具有最高優先級的實時任務就能得到優先處理,即使在嚴重負載下仍有實時性保證。

目前較新的 Linux 2.6.17 還不支持中斷線程化。但由 Ingo Molnar 設計并實現的實時補丁,實現了中斷線程化。最新的下載地址為:

http://people.redhat.com/~mingo/realtime-preempt/patch-2.6.17-rt9

下面將對中斷線程化進行簡要分析。

在初始化階段,中斷線程化的中斷初始化與常規中斷初始化大體上相同,在?start_kernel()?函數中都調用了?trap_init()?和?init_IRQ()?兩個函數來初始化?irq_desc_t?結構體,不同點主要體現在內核初始化創建?init?線程時,中斷線程化的中斷在?init()?函數中還將調用init_hardirqs(kernel/irq/manage.c(已經打過上文提到的補丁)),來為每一個 IRQ 創建一個內核線程,最高實時優先級為 50,依次類推直到 25,因此任何 IRQ 線程的最低實時優先級為 25。

void __init init_hardirqs(void)
{
……for (i = 0; i < NR_IRQS; i++) {irq_desc_t *desc = irq_desc + i;if (desc->action && !(desc->status & IRQ_NODELAY))desc->thread = kthread_create(do_irqd, desc, "IRQ %d", irq);……}
}
static int do_irqd(void * __desc)
{……/** Scale irq thread priorities from prio 50 to prio 25*/param.sched_priority = curr_irq_prio;if (param.sched_priority > 25)curr_irq_prio = param.sched_priority - 1;……
}

如果某個中斷號狀態位中的?IRQ_NODELAY?被置位,那么該中斷不能被線程化。

在中斷處理階段,兩者之間的異同點主要體現在:兩者相同的部分是當發生中斷時,CPU 將調用?do_IRQ()?函數來處理相應的中斷,do_IRQ()在做了必要的相關處理之后調用?__do_IRQ()。兩者最大的不同點體現在?__do_IRQ()?函數中,在該函數中,將判斷該中斷是否已經被線程化(如果中斷描述符的狀態字段不包含?IRQ_NODELAY?標志,則說明該中斷被線程化了),對于沒有線程化的中斷,將直接調用handle_IRQ_event()?函數來處理。

fastcall notrace unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
{
……if (redirect_hardirq(desc))goto out_no_end;
……
action_ret = handle_IRQ_event(irq, regs, action);
……
}
int redirect_hardirq(struct irq_desc *desc)
{
……if (!hardirq_preemption || (desc->status & IRQ_NODELAY) || !desc->thread)return 0;
……if (desc->thread && desc->thread->state != TASK_RUNNING)wake_up_process(desc->thread);
……
}

對于已經線程化的情況,調用?wake_up_process()?函數喚醒中斷處理線程,并開始運行,內核線程將調用?do_hardirq()?來處理相應的中斷,該函數將判斷是否有中斷需要被處理,如果有就調用?handle_IRQ_event()?來處理。handle_IRQ_event()?將直接調用相應的中斷處理函數來完成中斷處理。

不難看出,不管是線程化還是非線程化的中斷,最終都會執行?handle_IRQ_event()?函數來調用相應的中斷處理函數,只是線程化的中斷處理函數是在內核線程中執行的。

并不是所有的中斷都可以被線程化,比如時鐘中斷,主要用來維護系統時間以及定時器等,其中定時器是操作系統的脈搏,一旦被線程化,就有可能被掛起,這樣后果將不堪設想,所以不應當被線程化。如果某個中斷需要被實時處理,它可以像時鐘中斷那樣,用?SA_NODELAY?標志來聲明自己非線程化,例如:

static struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT | SA_NODELAY, CPU_MASK_NONE, "timer", NULL, NULL
};

其中,SA_NODELAY?到?IRQ_NODELAY?之間的轉換,是在?setup_irq()?函數中完成的。

回頁首

中斷負載均衡—SMP體系結構下的中斷

中斷負載均衡的實現主要封裝在?arch\ arch\i386\kernel\io-apic.c?文件中。如果在編譯內核時配置了?CONFIG_IRQBALANCE?選項,那么 SMP 體系結構中的中斷負載均衡將以模塊的形式存在于內核中。

late_initcall(balanced_irq_init);
#define late_initcall(fn)		module_init(fn)  //include\linux\init.h

在?balanced_irq_init()?函數中,將創建一個內核線程來負責中斷負載均衡:

static int __init balanced_irq_init(void)
{   ……printk(KERN_INFO "Starting balanced_irq\n");if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) return 0;else printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");……
}

在?balanced_irq()?函數中,每隔 5HZ=5s 的時間,將調用一次?do_irq_balance()?函數,進行中斷的遷徙。將重負載 CPU 上的中斷遷移到較空閑的CPU上進行處理。

回頁首

總結

隨著中斷親和力和中斷線程化的相繼實現,Linux 內核在 SMP 和實時性能方面的表現越來越讓人滿意,完全有理由相信,在不久的將來,中斷線程化將被合并到基線版本中。本文對中斷線程化的分析只是起一個拋磚引玉的作用,當新特性發布時,不至于讓人感到迷茫。

  • 注釋 1:輪詢也不是毫無用處,比如NAPI,就是輪詢與中斷相結合的經典案例。













本文轉自張昺華-sky博客園博客,原文鏈接:http://www.cnblogs.com/sky-heaven/p/5027417.html,如需轉載請自行聯系原作者

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

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

相關文章

SQL Server表分區

SQL Server表分區 什么是表分區 一般情況下&#xff0c;我們建立數據庫表時&#xff0c;表數據都存放在一個文件里。 但是如果是分區表的話&#xff0c;表數據就會按照你指定的規則分放到不同的文件里&#xff0c;把一個大的數據文件拆分為多個小文件&#xff0c;還可以把這…

apt 根據注解,編譯時生成代碼

apt&#xff1a; Retention后面的值&#xff0c;設置的為CLASS&#xff0c;說明就是編譯時動態處理的。一般這類注解會在編譯的時候&#xff0c;根據注解標識&#xff0c;動態生成一些類或者生成一些xml都可以&#xff0c;在運行時期&#xff0c;這類注解是沒有的~~會依靠動態生…

Web.config配置文件詳解(新手必看)

花了點時間整理了一下ASP.NET Web.config配置文件的基本使用方法。很適合新手參看&#xff0c;由于Web.config在使用很靈活&#xff0c;可以自定義一些節點。所以這里只介紹一些比較常用的節點。 <?xml version"1.0"?> <!--注意: 除了手動編輯此文件以外&…

Hello Playwright:(6)與元素交互

在上一節我們已經了解到如何定位到元素&#xff0c;那么接下來就可以與元素進行交互了。下面的例子都是以百度首頁作為測試頁面輸入文本FillAsync方法用于模擬用戶選中元素并輸入文本&#xff0c;這會觸發元素的 input 事件。該方法只適合<input>、<textarea>等可輸…

C語言試題四十六之將m行n列的二維數組中的字符數據,按列的順序依次放到一個字符串中。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 請編寫一個…

【MATLAB統計分析與應用100例】案例007:matlab數據的極差歸一化變換

文章目錄 1. 調用rand函數產生一個10行,4列的隨機矩陣,每列服從不同的均勻分布2. 調用rscore函數對x按列進行極差規格化變換, 返回變換后矩陣R,以及矩陣x各列的最小值構成的向量xmin,各列的極差構成的向量xrange1. 調用rand函數產生一個10行,4列的隨機矩陣,每列服從不同…

十二、動態座位響應及用戶訂票《仿淘票票系統前后端完全制作(除支付外)》

一、動態座位設置及發布 首先打開在線編輯器進入我們的項目&#xff1a;https://editor.ivx.cn/ 上一節中已經完成了座位設置的準備&#xff0c;這一節咱們將完成座位設置及發布的功能。 咱們首先給有座位設置事件&#xff1a; 有座位的事件設置當點擊后更改當前的內容為0即…

跨服務器 快速 導入數據表記錄 Insert into SELECT

Use DataBaseName/*開啟Ad Hoc Distributed Queries組件exec sp_configure show advanced options,1 reconfigure exec sp_configure Ad Hoc Distributed Queries,1 reconfigure*/Insert into tableName (col1&#xff0c;col2&#xff0c;col3&#xff0c;……) --字段不能含有…

C# 查詢大型數據集

LINQ 語法非常好&#xff0c;但其作用是什么&#xff1f;我們只要查看源數組&#xff0c;就可以看出需要的結果&#xff0c;為什么要查詢這種一眼就能看出結果的數據源呢&#xff1f;有時查詢的結果不那么明顯&#xff0c;在下面的示例中&#xff0c;就創建了一個非常大的數字數…

C語言試題四十七之程序定義了N×M的二維數組,并在主函數中自動賦值。請編寫函數function(int a[N][M], int m),該函數的功能是:將數組右上半三角元素中的值乘以m。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 程序定義了…

第六章 三大消息摘要算法總結

6.1、MD5 推薦使用CC&#xff08;即Commons Codec&#xff09;實現雖然已被破解&#xff0c;但是仍舊廣泛用于注冊登錄模塊與驗證下載的文件的完整性可以自己寫一個注冊登錄模塊&#xff1b;自己下載一個MD5加密的文件&#xff0c;然后通過之前編寫的工具類&#xff08;或者使用…

一、博客首頁搭建搭建《iVX低代碼仿CSDN個人博客制作》

制作iVX 低代碼項目需要進入在線IDE&#xff1a;https://editor.ivx.cn/ 一、頭部導航欄思路參考 首先我們可以查看CSDN的博客首頁&#xff0c;從中查看一下布局&#xff1a; 在以上首頁中&#xff0c;我們可以得知其頂部為一個整行&#xff0c;這個行內容左側為一個logo&am…

【MATLAB統計分析與應用100例】案例008:調用rand函數生成均勻分布隨機數

文章目錄 1. 生成隨機數分布直方圖2. 生成隨機數矩陣,服從均勻分布1. 生成隨機數分布直方圖 x = rand(10) % 生成10行10列的隨機數矩陣,其元素服從[0,1]上均勻分布 y = x(:)

linux samba服務器

本文轉自wanglm51051CTO博客&#xff0c;原文鏈接&#xff1a; http://blog.51cto.com/studyit2016/1890282&#xff0c;如需轉載請自行聯系原作者

modernizer的意義

modernizer是一個js文件&#xff0c;會檢查當前的瀏覽器支持什么特性&#xff0c;就在Html標簽上添加什么類&#xff0c;然后如果不支持添加no-xxx類&#xff0c;這樣&#xff0c;就可以針對兩種情況寫兩種css。 http://blog.chinaunix.net/uid-21633169-id-4286857.html轉載于…

拆分備份(還原)比較大的數據庫為多個bak文件

工作中由于個別數據庫比較大&#xff0c;生成的備份文件也比較大&#xff0c;不方便存儲或者轉移&#xff0c;可以將文件備份為多個小的bak文件。 比如一個200G的數據庫&#xff0c;可以拆分備份為10個bak文件&#xff0c;則每個bak文件約在20G左右。 備份代碼&#xff1a; /…

C語言試題四十八之該函數可以統計一個長度為2的字符串在另一個字符串中出現的次數。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 請編寫一個…

Rafy 框架 - 幽靈插件(假刪除)

Rafy 框架又添新成員&#xff1a;幽靈插件。本文將解釋該插件的場景、使用方法、原理。 場景 在開發各類數據庫應用系統時&#xff0c;往往需要在刪除數據時不是真正地刪除數據&#xff0c;而只是把數據標識為‘已刪除’狀態。這些數據在業務邏輯上是已經完全刪除、不可用的數據…

C#-Linq源碼解析之Average

前言在Dotnet開發過程中&#xff0c;Average作為IEnumerable的擴展方法&#xff0c;十分常用。本文對Average方法的關鍵源碼進行簡要分析&#xff0c;以方便大家日后更好的使用該方法。使用Average 計算數值序列的平均值假如我們有這樣的一個集合List<int> grades new L…

二、博客首頁完成《iVX低代碼仿CSDN個人博客制作》

制作iVX 低代碼項目需要進入在線IDE&#xff1a;https://editor.ivx.cn/ 一、菜單思路參考及制作 在 CSDN 首頁中的菜單部分為一串橫排的內容&#xff0c;并且可以進行拖動&#xff1a; 首先咱們添加一個行&#xff0c;命名為菜單&#xff1a; 接著肯定是需要設置上下的內邊…