當前位置:首頁 » 操作系統 » linuxmsleep

linuxmsleep

發布時間: 2023-02-07 23:56:01

Ⅰ 一文搞懂 , linux內核—— 同步管理(下)

上面講的自旋鎖,信號量和互斥鎖的實現,都是使用了原子操作指令。由於原子操作會 lock,當線程在多個 CPU 上爭搶進入臨界區的時候,都會操作那個在多個 CPU 之間共享的數據 lock。CPU 0 操作了 lock,為了數據的一致性,CPU 0 的操作會導致其他 CPU 的 L1 中的 lock 變成 invalid,在隨後的來自其他 CPU 對 lock 的訪問會導致 L1 cache miss(更准確的說是communication cache miss),必須從下一個 level 的 cache 中獲取。

這就會使緩存一致性變得很糟,導致性能下降。所以內核提供一種新的同步方式:RCU(讀-復制-更新)。

RCU 解決了什麼

RCU 是讀寫鎖的高性能版本,它的核心理念是讀者訪問的同時,寫者可以更新訪問對象的副本,但寫者需要等待所有讀者完成訪問之後,才能刪除老對象。讀者沒有任何同步開銷,而寫者的同步開銷則取決於使用的寫者間同步機制。

RCU 適用於需要頻繁的讀取數據,而相應修改數據並不多的情景,例如在文件系統中,經常需要查找定位目錄,而對目錄的修改相對來說並不多,這就是 RCU 發揮作用的最佳場景。

RCU 例子

RCU 常用的介面如下圖所示:

為了更好的理解,在剖析 RCU 之前先看一個例子:

#include<linux/kernel.h>#include<linux/mole.h>#include<linux/init.h>#include<linux/slab.h>#include<linux/spinlock.h>#include<linux/rcupdate.h>#include<linux/kthread.h>#include<linux/delay.h>structfoo{inta;structrcu_headrcu;};staticstructfoo*g_ptr;staticintmyrcu_reader_thread1(void*data)//讀者線程1{structfoo*p1=NULL;while(1){if(kthread_should_stop())break;msleep(20);rcu_read_lock();mdelay(200);p1=rcu_dereference(g_ptr);if(p1)printk("%s: read a=%d\n",__func__,p1->a);rcu_read_unlock();}return0;}staticintmyrcu_reader_thread2(void*data)//讀者線程2{structfoo*p2=NULL;while(1){if(kthread_should_stop())break;msleep(30);rcu_read_lock();mdelay(100);p2=rcu_dereference(g_ptr);if(p2)printk("%s: read a=%d\n",__func__,p2->a);rcu_read_unlock();}return0;}staticvoidmyrcu_del(structrcu_head*rh)//回收處理操作{structfoo*p=container_of(rh,structfoo,rcu);printk("%s: a=%d\n",__func__,p->a);kfree(p);}staticintmyrcu_writer_thread(void*p)//寫者線程{structfoo*old;structfoo*new_ptr;intvalue=(unsignedlong)p;while(1){if(kthread_should_stop())break;msleep(250);new_ptr=kmalloc(sizeof(structfoo),GFP_KERNEL);old=g_ptr;*new_ptr=*old;new_ptr->a=value;rcu_assign_pointer(g_ptr,new_ptr);call_rcu(&old->rcu,myrcu_del);printk("%s: write to new %d\n",__func__,value);value++;}return0;}staticstructtask_struct*reader_thread1;staticstructtask_struct*reader_thread2;staticstructtask_struct*writer_thread;staticint__initmy_test_init(void){intvalue=5;printk("figo: my mole init\n");g_ptr=kzalloc(sizeof(structfoo),GFP_KERNEL);reader_thread1=kthread_run(myrcu_reader_thread1,NULL,"rcu_reader1");reader_thread2=kthread_run(myrcu_reader_thread2,NULL,"rcu_reader2");writer_thread=kthread_run(myrcu_writer_thread,(void*)(unsignedlong)value,"rcu_writer");return0;}staticvoid__exitmy_test_exit(void){printk("goodbye\n");kthread_stop(reader_thread1);kthread_stop(reader_thread2);kthread_stop(writer_thread);if(g_ptr)kfree(g_ptr);}MODULE_LICENSE("GPL");mole_init(my_test_init);mole_exit(my_test_exit);

執行結果是:

myrcu_reader_thread2:reada=0myrcu_reader_thread1:reada=0myrcu_reader_thread2:reada=0myrcu_writer_thread:writetonew5myrcu_reader_thread2:reada=5myrcu_reader_thread1:reada=5myrcu_del:a=0

RCU 原理

可以用下面一張圖來總結,當寫線程 myrcu_writer_thread 寫完後,會更新到另外兩個讀線程 myrcu_reader_thread1 和 myrcu_reader_thread2。讀線程像是訂閱者,一旦寫線程對臨界區有更新,寫線程就像發布者一樣通知到訂閱者那裡,如下圖所示。

寫者在拷貝副本修改後進行 update 時,首先把舊的臨界資源數據移除(Removal);然後把舊的數據進行回收(Reclamation)。結合 API 實現就是,首先使用 rcu_assign_pointer 來移除舊的指針指向,指向更新後的臨界資源;然後使用 synchronize_rcu 或 call_rcu 來啟動 Reclaimer,對舊的臨界資源進行回收(其中 synchronize_rcu 表示同步等待回收,call_rcu 表示非同步回收)。

為了確保沒有讀者正在訪問要回收的臨界資源,Reclaimer 需要等待所有的讀者退出臨界區,這個等待的時間叫做寬限期(Grace Period)。

Grace Period

中間的黃色部分代表的就是 Grace Period,中文叫做寬限期,從 Removal 到 Reclamation,中間就隔了一個寬限期,只有當寬限期結束後,才會觸發回收的工作。寬限期的結束代表著 Reader 都已經退出了臨界區,因此回收工作也就是安全的操作了。

寬限期是否結束,與 CPU 的執行狀態檢測有關,也就是檢測靜止狀態 Quiescent Status。

Quiescent Status

Quiescent Status,用於描述 CPU 的執行狀態。當某個 CPU 正在訪問 RCU 保護的臨界區時,認為是活動的狀態,而當它離開了臨界區後,則認為它是靜止的狀態。當所有的 CPU 都至少經歷過一次 Quiescent Status 後,寬限期將結束並觸發回收工作。

因為 rcu_read_lock 和 rcu_read_unlock 分別是關閉搶占和打開搶占,如下所示:

staticinlinevoid__rcu_read_lock(void){preempt_disable();}

staticinlinevoid__rcu_read_unlock(void){preempt_enable();}

所以發生搶占,就說明不在 rcu_read_lock 和 rcu_read_unlock 之間,即已經完成訪問或者還未開始訪問。

Linux 同步方式的總結

資料免費領

學習直通車

Ⅱ 如何在載入模塊時向模塊傳遞參數值

1. 現象描述

Linux系統中,動態載入的模塊往往需要實現:
1)在載入模塊時,向模塊傳遞一個參數值,且該參數值在模塊運行過程中不能對其進行修改;
2)在載入模塊時,向模塊傳遞一個參數值,且該參數值在模塊運行過程中根據需求對其進行動態修改。
2. 關鍵過程

1、Linux系統2.6內核下,可以通過宏mole_param(name, type, perm)將參數name聲明為模塊參數,該參數值可以在載入模塊時指定,否則為模塊內定義的預設值;
2、我們需要關注perm,perm表示此參數在sysfs文件系統中所對應的文件節點的屬性:
1)當perm為0時,表示此參數不存在在sysfs文件系統下對應的文件節點;
2)模塊被載入後,在/sys/mole/目錄下將出現以此模塊名命名的目錄;
3)如果此模塊存在perm不為0的命令行參數,在此模塊的目錄下將出現parameters目錄,包含一系列以參數命名的文件節點;
4)這些文件的許可權值等於perm,文件的內容為參數的值。
3、perm有四種不同屬性的模塊參數:
1)可讀寫參數:此參數可以實時查看和動態修改其值;其屬性為S_IRUGO|S_IWUSR;
2)可讀參數:此參數只能實時查看,不能動態修改;其屬性為S_IRUGO;
3)可寫參數:此參數不能實時查看,但可以動態修改;其屬性為S_IWUSR;
4)不可讀寫參數:此參數不能在sysfs文件系統中顯示,也不能實時查看和動態修改其值;其屬性值為0;
由此我們可以通過設置不同的perm值,實現不同參數不同的控制。
3. 案例實現

3.1. Demo說明

1、demo程序定義了2各模塊參數,分別為uid、period。載入模塊時,可以向模塊傳遞這兩個參數的值,否則這兩個參數值將為默認值;模塊運行過程中,兩者均可被用戶、用戶所在組及其他組讀取,後者還可被用戶修改。
2、demo程序使用到的perm許可權值含義:
S_IRUGO:S_IRUSR|S_IRGRP|S_IROTH,表示可以被用戶、用戶所在組及其他組讀取且只讀;
S_IWUSR:表示可以被用戶(能動態載入模塊的用戶必須是超級用戶)修改。
3、demo程序根據uid和period列印不同的信息;當period值變化時,會再次列印信息。
4、demo程序使用說明如下:
1)載入模塊時:insmod demo.ko uid=0 period =0
2)模塊運行過程中,讀取uid值:cat /sys/mole/demo/parameters/uid
3) 模塊運行過程中,修改period值:echo 1 > /sys/mole/demo/parameters/period
3.2. 源文件
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/version.h>
#include <linux/moleparam.h>
#include <linux/device.h>
#include <linux/mole.h>
#include <linux/string.h>
#include <linux/dma-mapping.h>
#include <asm/semaphore.h>
#include <asm/page.h>
typedef uint8_t bool_t;

#define MORNING 0
#define AFTERNOON 1
#define EVENING 2
#define UNKNOWN 3

#define FALSE 0
#define TRUE 1

#define USER_NUM 3

/******** mole information ***************/
MODULE_AUTHOR("H3C Corporation");
MODULE_DESCRIPTION("Demo function");
MODULE_LICENSE("GPL");

/******** mole parameters ***************/
static uint uid = 0;
mole_param(uid, uint, S_IRUGO);

static uint period = MORNING;
mole_param(period, uint, S_IRUGO|S_IWUSR);

/******** global parameters ***************/
char user_name[USER_NUM][20] = {{"wuwu"}, {"pikaqiu"}, {"lala"}};
uint prev_period = UNKNOWN;
bool_t demo_quit = FALSE;
struct completion com_demo;

int demo_thread(void* unuse)
{
daemonize("demo_thread");

for(;;)
{
if(demo_quit)
{
break;
}

if(prev_period != period)
{
if(MORNING == period)
{
printk(KERN_EMERG "Good morning, %s/n", user_name[uid]);
}
else if(AFTERNOON == period)
{
printk(KERN_EMERG "Good afternoon, %s/n", user_name[uid]);

}
else if(EVENING == period)
{
printk(KERN_EMERG "Good evening, %s/n", user_name[uid]);
}
else
{
printk(KERN_EMERG "Parameter period is invalid! Please choose from follows:/n");
printk(KERN_EMERG "0: means morning/n");
printk(KERN_EMERG "1: means afternoon/n");
printk(KERN_EMERG "2: means evening/n");
printk(KERN_EMERG "/n");
}

prev_period = period;
}

msleep(10);
}

complete_and_exit(&com_demo, 0);
}

static int __init demo_init(void)
{
pid_t pid = 0;
uint32_t i = 0;

if(uid >= USER_NUM)
{
printk(KERN_EMERG "Parameter uid is invalid, please choose from follows:/n");
for(i=0; i<USER_NUM; i++)
{
printk(KERN_EMERG "i: named %s/n", user_name[i]);
}
printk(KERN_EMERG "/n");

return -1;
}

init_completion(&com_demo);
pid = kernel_thread(demo_thread, NULL, CLONE_KERNEL);
if(pid < 0)
{
printk(KERN_EMERG "demo thread create failed!/n");
return -1;
}

printk(KERN_EMERG "Welcome to the demo!/n");
return 0;
}

static void __exit demo_exit(void)
{
demo_quit = TRUE;
wait_for_completion(&com_demo);
printk(KERN_EMERG "Byebye, %s/n", user_name[uid]);
return;
}

mole_init(demo_init);
mole_exit(demo_exit);
4. 經驗總結

1、根據對不同用戶許可權要求設置perm位;
2、對於只需在載入模塊時傳遞參數值、而不希望用戶看到該參數,建議將perm位置為0。

Ⅲ linux中如何實現sleep(0)的功能

linux下的sleep(0),有些時候被實現為下面這樣:

unsigned int sleep (unsigned int seconds)
{
……
/* This is not necessary but some buggy programs depend on this. */
if (seconds == 0)
return 0;
……
}

如果你的程序對實時性要求不那麼高,可以使用usleep(1),不然就只能用信號或者其他事件機制了。

Ⅳ qt界面不動,但是響應事件

無響應情況的發生與QT版本(本noob使用的Qt Creator 4.8.0 (Enterprise))無關,在QT使用時突然發作。
表現為內存佔用不斷上升,直至到達內存上限後QT閃退123
結合廣大博友的相似案例,以及自己成功的解決方案,初步判斷為QT無響應和顯卡/顯示驅動/其他軟體的進程干涉有關。
解決方案

顯卡問題
運行QtCreator的時候不支持某些顯卡或者不支持高性能圖形處理器
方法1(筆記本適用,台式PC可能不行)

你使用的獨立顯卡有可能不兼容QT,首選圖形處理器選擇為自動選擇或者集成圖形
引用來自https://blog.csdn.net/Hxj_CSDN/article/details/80630420的圖片

方法2(適用不存在上述方法的首選圖形處理器選項的台式PC)

inter i系列cpu自帶集成顯示處理。所以直接禁用獨立顯卡便可以切換成集成圖形。
在這里插入圖片描述
顯卡驅動原因

想一想最近有沒有更新顯卡驅動或者安裝NVIDIA相關驅動(如 3D vision)
將其卸載安裝舊穩定版本顯卡驅動,或者卸載3D vision
其他軟體進程的干涉(如HOOK)

已知有道詞典的劃詞取詞功能(可能是用了信息鉤子)會導致QT無響應的BUG。
1還有可能是上層屏幕顯示的軟體導致QT無響應。
請盡量關閉其他軟體進程,再重新進入QT排除原因。如果實錘了,那當然就不能同時使用了!
其他可能的解決辦法

刪除 ~\AppData\Roaming\QtProject文件夾,然後再打開Qt Creator即可。
該文件夾經本noob的試驗是用於存儲QT個人設置以及歷史項目目錄等文件的,大可刪除,QT會在重新打開時自動生成,只不過你相關的設置就會恢復默認值了!!!
Linux下,~是/home/YourUserName
Windows下,~是C:\Users\YourUserName

Ⅳ 請問在linux下的紅外介面如何驅動

延時一般兩種,mdelay這種忙等待的,多少大體就是多少,msleep這種調度的,多少就不是多少,因為裡面有個調度時間。你可以自己用示波器抓一下時間就知道了。

Ⅵ qt sleep函數哪個頭文件

QT雖然沒有提供Sleep(),但是QT提供了系統調用,然而每個系統中都有Sleep()函數,所以可以簡單的包含系統頭文件即可。

如果是windows平台則:
#include <windows.h>
就可以用Sleep()了:
Sleep(10000);
(注意是大寫S)linux下頭文件是:
#include <sys/stat.h>

Ⅶ 在system-top.dts中描述USB設備

1. 開機後,usb功能正常初始化;這時插入usb的U盤,或者hub;則首先調用如下代碼。

static int hcd_pci_runtime_resume(struct device *dev){ int retval; powermac_set_asic(to_pci_dev(dev), 1); retval = resume_common(dev, PM_EVENT_AUTO_RESUME); dev_dbg(dev, "hcd_pci_runtime_resume: %d\n", retval); return retval;}

然後繼續調用:
static int resume_common(struct device *dev, int event){ struct pci_dev *pci_dev = to_pci_dev(dev); struct usb_hcd *hcd = pci_get_drvdata(pci_dev); int retval; if (HCD_RH_RUNNING(hcd) || (hcd->shared_hcd && HCD_RH_RUNNING(hcd->shared_hcd))) { dev_dbg(dev, "can't resume, not suspended!\n"); return 0; } retval = pci_enable_device(pci_dev); if (retval < 0) { dev_err(dev, "can't re-enable after resume, %d!\n", retval); return retval; } pci_set_master(pci_dev); if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) { /* * Only EHCI controllers have to wait for their companions. * No locking is needed because PCI controller drivers do not * get unbound ring system resume. */ if (pci_dev->class == CL_EHCI && event != PM_EVENT_AUTO_RESUME) for_each_companion(pci_dev, hcd, ehci_wait_for_companions); retval = hcd->driver->pci_resume(hcd, event == PM_EVENT_RESTORE); if (retval) { dev_err(dev, "PCI post-resume error %d!\n", retval); if (hcd->shared_hcd) usb_hc_died(hcd->shared_hcd); usb_hc_died(hcd); } } return retval;}

在 代碼 hcd->driver->pci_resume() 里, 調用函數如下:
static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated){ struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); int retval = 0; /* Due to one HW bug, XHCI will keep generating PME wakeups and fail * to stay in runtime suspended state, so required to clear the internal * PME flag once it is back to D0 as the software workaround */ if (xhci->quirks & XHCI_SPURIOUS_PME) { xhci_intel_clr_internal_pme_flag(xhci); xhci_intel_ssic_port_unused(xhci, 0); } /* The BIOS on systems with the Intel Panther Point chipset may or may * not support xHCI natively. That means that ring system resume, it * may switch the ports back to EHCI so that users can use their * keyboard to select a kernel from GRUB after resume from hibernate. * * The BIOS is supposed to remember whether the OS had xHCI ports * enabled before resume, and switch the ports back to xHCI when the * BIOS/OS semaphore is written, but we all know we can't trust BIOS * writers. * * Unconditionally switch the ports back to xHCI after a system resume. * It should not matter whether the EHCI or xHCI controller is * resumed first. It's enough to do the switchover in xHCI because * USB core won't notice anything as the hub driver doesn't start * running again until after all the devices (including both EHCI and * xHCI host controllers) have been resumed. */ if (pdev->vendor == PCI_VENDOR_ID_INTEL) usb_enable_intel_xhci_ports(pdev); retval = xhci_resume(xhci, hibernated); return retval;}

然後調用函數,xhci_resume();
int xhci_resume(struct xhci_hcd *xhci, bool hibernated){ u32 command, temp = 0, status; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; int retval = 0; bool comp_timer_running = false; pr_info("wgq[%s-%d] hibernated[%d]\n",__func__,__LINE__,hibernated); /* Wait a bit if either of the roothubs need to settle from the * transition into bus suspend. */ if (time_before(jiffies, xhci->bus_state[0].next_statechange) || time_before(jiffies, xhci->bus_state[1].next_statechange)) msleep(100); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); spin_lock_irq(&xhci->lock); if (xhci->quirks & XHCI_RESET_ON_RESUME) hibernated = true; if (!hibernated) { /* step 1: restore register */ xhci_restore_registers(xhci); /* step 2: initialize command ring buffer */ xhci_set_cmd_ring_deq(xhci); /* step 3: restore state and start state*/ /* step 3: set CRS flag */ command = readl(&xhci->op_regs->command); command |= CMD_CRS; writel(command, &xhci->op_regs->command); if (xhci_handshake(xhci, &xhci->op_regs->status, STS_RESTORE, 0, 10 * 1000)) { xhci_warn(xhci, "WARN: xHC restore state timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } temp = readl(&xhci->op_regs->status); } /* If restore operation fails, re-initialize the HC ring resume */ if ((temp & STS_SRE) || hibernated) { if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !(xhci_all_ports_seen_u0(xhci))) { del_timer_sync(&xhci->comp_mode_recovery_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "Compliance Mode Recovery Timer deleted!"); } /* Let the USB core know _both_ roothubs lost power. */ usb_root_hub_lost_power(xhci->main_hcd->self.root_hub); usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub); xhci_dbg(xhci, "Stop HCD\n"); xhci_halt(xhci); xhci_reset(xhci); spin_unlock_irq(&xhci->lock); xhci_cleanup_msix(xhci); xhci_dbg(xhci, "// Disabling event ring interrupts\n"); temp = readl(&xhci->op_regs->status); writel(temp & ~STS_EINT, &xhci->op_regs->status); temp = readl(&xhci->ir_set->irq_pending); writel(ER_IRQ_DISABLE(temp), &xhci->ir_set->irq_pending); xhci_print_ir_set(xhci, 0); xhci_dbg(xhci, "cleaning up memory\n"); xhci_mem_cleanup(xhci); xhci_dbg(xhci, "xhci_stop completed - status = %x\n", readl(&xhci->op_regs->status)); /* USB core calls the PCI reinit and start functions twice: * first with the primary HCD, and then with the secondary HCD. * If we don't do the same, the host will never be started. */ if (!usb_hcd_is_primary_hcd(hcd)) secondary_hcd = hcd; else secondary_hcd = xhci->shared_hcd; xhci_dbg(xhci, "Initialize the xhci_hcd\n"); retval = xhci_init(hcd->primary_hcd); if (retval) return retval; comp_timer_running = true; xhci_dbg(xhci, "Start the primary HCD\n"); retval = xhci_run(hcd->primary_hcd); if (!retval) { xhci_dbg(xhci, "Start the secondary HCD\n"); retval = xhci_run(secondary_hcd); } hcd->state = HC_STATE_SUSPENDED; xhci->shared_hcd->state = HC_STATE_SUSPENDED; goto done; } /* step 4: set Run/Stop bit */ command = readl(&xhci->op_regs->command); command |= CMD_RUN; writel(command, &xhci->op_regs->command); xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, 0, 250 * 1000); xhci_resume_pending_ports(xhci); /* step 5: walk topology and initialize portsc, * portpmsc and portli */ /* this is done in bus_resume */ /* step 6: restart each of the previously * Running endpoints by ringing their doorbells */ spin_unlock_irq(&xhci->lock);done: if (retval == 0) { /* Resume root hubs only when have pending events. */ status = readl(&xhci->op_regs->status); if (status & STS_EINT) { usb_hcd_resume_root_hub(hcd); usb_hcd_resume_root_hub(xhci->shared_hcd); } } /* * If system is subject to the Quirk, Compliance Mode Timer needs to * be re-initialized Always after a system resume. Ports are subject * to suffer the Compliance Mode issue again. It doesn't matter if * ports have entered previously to U0 before system's suspension. */ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running) compliance_mode_recovery_timer_init(xhci); /* Re-enable port polling. */ xhci_dbg(xhci, "%s: starting port polling.\n", __func__); set_bit(HCD_FLAG_POLL_RH, &hcd->flags); usb_hcd_poll_rh_status(hcd); return retval;}

Ⅷ linux內核中mdelay怎麼實現

1.udelay(); mdelay(); ndelay();實現的原理本質上都是忙等待,ndelay和mdelay都是通過udelay衍生出來的,我們使用這些函數的實現往往會碰到編譯器的警告implicit declaration of function'udelay',這往往是由於頭文件的使用不當造成的。在include/asm-???/delay.h中定義了udelay(),而在include/linux/delay.h中定義了mdelay和ndelay. udelay一般適用於一個比較小的delay,如果你填的數大於2000,系統會認為你這個是一個錯誤的delay函數,因此如果需要2ms以上的delay需要使用mdelay函數。 2.由於這些delay函數本質上都是忙等待,對於長時間的忙等待意味這無謂的耗費著cpu的資源,因此對於毫秒級的延時,內核提供了msleep,ssleep等函數,這些函數將使得調用它的進程睡眠參數指定的時間。 應用層: #include <unistd.h> 1、unsigned int sleep(unsigned int seconds); 秒級 2、int usleep(useconds_t usec); 微秒級:1/10^-6 #define _POSIX_C_SOURCE 199309 #include <time.h> 3、int nanosleep(const struct timespec *req, struct timespec *rem); struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; // The value of the nanoseconds field must be in the range 0 to 999999999. 內核層: include <linux/delay.h> 1、void ndelay(unsigned long nsecs); 納秒級:1/10^-10 2、void udelay(unsigned long usecs); 微秒級: 1/10^-6 3、void mdelay(unsigned long msecs); 毫秒級:1/10^-3 sleep_on(), interruptible_sleep_on(); sleep_on_timeout(), interruptible_sleep_on_timeout(); 根據你的情況選用這些函數,注意: sleep操作在kernel必須小心、小心。。。 udelay()等函數是cpu忙等,沒有傳統意義上的sleep。這些函數相當於我們平時的阻塞讀、寫之類的語義,主要用於等外設完成某些操作

Ⅸ linux內核編程能不能使用sleep函數,有沒有代替的方法

沒有sleep

常用用jiffies、ndelay、mdelay等

msleep和ssleep不可中斷。很少見。

熱點內容
生辰演算法 發布:2025-07-22 01:01:38 瀏覽:497
補牙材料壓縮 發布:2025-07-22 01:00:33 瀏覽:289
趨勢多空指標源碼 發布:2025-07-22 00:34:53 瀏覽:170
opencvpython3mac 發布:2025-07-22 00:22:07 瀏覽:699
java獲取方法 發布:2025-07-22 00:17:45 瀏覽:240
讀書軟體視頻分鏡頭廣告腳本 發布:2025-07-21 23:32:00 瀏覽:60
演算法ecd 發布:2025-07-21 23:29:05 瀏覽:704
安卓會玩叫什麼 發布:2025-07-21 23:23:00 瀏覽:354
備用域伺服器搭建 發布:2025-07-21 23:22:59 瀏覽:599
編譯yacc教程 發布:2025-07-21 23:21:51 瀏覽:353