亚洲国产第一_开心网五月色综合亚洲_日本一级特黄特色大片免费观看_久久久久久久久久免观看

Hello! 歡迎來到小浪云!


深度解析如何在Linux中創建自己的第一個系統程序—進度條


avatar
小浪云 2025-04-17 26

&&

在我們的編譯器里面我們只想 進行回車的話,那么我們就是

我們之前在vs2022里面的 是回車且換行

但是今天我們的這里的 和在這個不是一個概念

其實回車換行其實是兩個動作的

行緩沖區

我們第一個進行編譯的時候我們加上 ,然后sleep兩秒

我們編譯運行可以發現我們的打印內容先出來然后進行等待兩秒

但是我們將這個 去掉的話,我們發現編譯的時候是等到了兩秒,這個打印的內容才出來的

深度解析如何在Linux中創建自己的第一個系統程序—進度條

我們帶 的話就是數據立即顯示

那么我們如果不帶 的話我們先執行printf還是sleep呢?

我們c語言一定是從上到下進行執行的

那么我們這里也是先執行printf也是執行sleep的

那么我們打印的數據怎么沒看見呢?

那么我們這時候的數據肯定是存在緩沖區里面的

等休眠時間結束了,我們就將我們打印的顯示出來

只要有緩沖區的話

那么一定存在這個刷新策略

顯示器的刷新策略:行刷新!

所以如果包含 的話立即打印到顯示器上

如果不包含的話改字符串不做刷新,要么程序要么結束自動刷新,要么我們進行強制刷新的操作

如果我們想讓不帶 的消息進行刷新的話怎么辦呢?

我們可以使用命令fflush

深度解析如何在Linux中創建自己的第一個系統程序—進度條

這個命令可以直接進行強制刷新的操作

我們在代碼中添加這個代碼就能立即進行刷新的操作

代碼語言:JavaScript代碼運行次數:0運行復制

#include <stdio.h>  2 #include<unistd.h>  3   4 int main()  5 {  6   printf("hello kaikai");  7   fflush(stdout);//利用這個文件流將我們的字符串立即進行刷新的操作         8   sleep(2);                                                         9   return 0;                                                        10 }     </unistd.h></stdio.h>
深度解析如何在Linux中創建自己的第一個系統程序—進度條

然后我們運行程序我們可以發現字符串立即被打印出來了

我們現在對code.c進行編輯

我們想讓結果在一行進行顯示的操作

但是我們最后呈現出來的是很多行

深度解析如何在Linux中創建自己的第一個系統程序—進度條
深度解析如何在Linux中創建自己的第一個系統程序—進度條

那么怎么樣讓我們的光標在寫完之后重新回到那一行呢?

我們可以將原來的 換成我們的 就行了

的作用是在輸出完畢之后光標能夠回到最開始的位置

深度解析如何在Linux中創建自己的第一個系統程序—進度條

但是我們又發現這個什么都不打印

深度解析如何在Linux中創建自己的第一個系統程序—進度條

因為我們這里后面不是 了,不會進行刷新操作的,我們打印的結果都是顯示在緩沖區里面的

那么我們就進行主動刷新的操作

我們在代碼的后面加上fflush(stdout);就行了

輸出后我們立即進行刷新,將我們的數字顯示出來

但是我們發現我們的數字一打印完就會消失了,光標一直回到開頭

最后被命令行覆蓋了

深度解析如何在Linux中創建自己的第一個系統程序—進度條
深度解析如何在Linux中創建自己的第一個系統程序—進度條

我們可以在代碼的最后加上這個 進行換行的操作

那么這里我們就完成了一個倒計時的裝置了

代碼語言:javascript代碼運行次數:0運行復制

#include <stdio.h>  2 #include<unistd.h>  3   4 int main()  5 {  6   int cnt=9;  7   while(cnt&gt;=0)  8   {  9     printf("%d ",cnt); 10     fflush(stdout);//利用這個文件流將我們的字符串立即進行刷新的操作 11     cnt--; 12     sleep(1); 13   } 14   printf(" ");                                                          15 //  printf("hello kaikai"); 16 //  fflush(stdout);//利用這個文件流將我們的字符串立即進行刷新的操作 17 //  sleep(2); 18   return 0; 19 }~     </unistd.h></stdio.h>
深度解析如何在Linux中創建自己的第一個系統程序—進度條

最終效果就是到了0我們就直接進行了換行的操作了

深度解析如何在Linux中創建自己的第一個系統程序—進度條

但是我們又發現我們將這個cnt初始化為10的話我們最后打印的就是這樣的

會在后面帶上一個0,這是為什么呢?

深度解析如何在Linux中創建自己的第一個系統程序—進度條

其實顯示器只認字符的

我們在打印的其實是以字符為單位進行打印的操作

我們第一個答應的是1和0兩個字符

那么第二次的時候我們的光標回到第一個字符了

然后我們打印9

但是我們之前的字符0沒有刪除

所以顯示的就是90

80

70

60

等等

那么我們怎么進行修改操作呢?

我們可以在我們的格式化那里進行修改的操作的

我們改變成%2d就行了

深度解析如何在Linux中創建自己的第一個系統程序—進度條

但是我們發現我們的這個空格打印的時候在左側的,我們想讓不足2位的空格在右邊

深度解析如何在Linux中創建自己的第一個系統程序—進度條

那么我們怎么辦?

我們是可以使用%-2d進行調整

因為我們格式化的時候,,不足位置的時候默認是右對齊的

那么我們加上-號就可以變成左對齊了

那么到這里我們就實現成功了

深度解析如何在Linux中創建自己的第一個系統程序—進度條

進度條實現

我們的Linux中的進度條通常是這樣的

深度解析如何在Linux中創建自己的第一個系統程序—進度條

隨著進步不斷增加,我們括號中的#就會增加,右邊的數字也是顯示的進度

然后右邊的斜杠就是我們的光標移動

我們這里聲明在.h文件中,實現在.c文件中,然后我們在main.c中進行編譯操作

深度解析如何在Linux中創建自己的第一個系統程序—進度條

我們將我們的Makefile文件拷貝到當前的目錄中

使用命令cp ../Makefile .將上級目錄中的Makefile文件拷貝到當前的文件中

那么這樣我們就成功了

深度解析如何在Linux中創建自己的第一個系統程序—進度條

我們只需要將這個Makefile里面的BIN就是生成的可執行文件的名稱進行改變下就行了,其他的不需要進行變化

深度解析如何在Linux中創建自己的第一個系統程序—進度條

我們然后進行正常的編譯操作,輸入命令make

深度解析如何在Linux中創建自己的第一個系統程序—進度條

我們在這里面引用了usleep的概念

下面的具體的使用方法

usleep 是一個 C 語言中的函數,定義在 頭文件中,用于讓程序暫停執行一段時間(微秒級別)。它的作用是引入延時,通常在需要控制程序執行速度或等待某些事件的場景下使用。


函數原型:代碼語言:javascript代碼運行次數:0運行復制

int usleep(useconds_t usec);

參數: usec:延時的時間,以微秒(microseconds)為單位。1 秒 = 1,000,000 微秒。 返回值: 成功時返回 0。 如果出錯(例如傳入了非法參數),則返回 -1 并設置 errno


使用場景:控制程序的執行速度: 在循環中延時一定時間,避免程序執行得過快。 常用于動畫、進度條、實時更新等。 等待硬件或外部事件:等待特定硬件響應,比如 GPIO 信號穩定。減少 CPU 占用率:在多線程程序中,為線程設置短暫的休眠以釋放 CPU 資源。


示例:

以下是一個簡單的例子,展示如何使用 usleep 實現動態進度條:

代碼語言:javascript代碼運行次數:0運行復制

#include <stdio.h>#include <unistd.h> // 包含 usleep 函數int main() {    printf("Loading... ");    for (int i = 0; i <p>運行效果: 程序每 50 毫秒更新一次,顯示動態的進度條效果。</p> <figure class=""><hr></figure>注意事項:跨平臺兼容性: usleep 是 POSIX 標準的一部分,因此在 Windows 平臺上可能無法使用。如果需要跨平臺的延時功能,可以使用其他方法,比如:  Sleep 函數(Windows 特有,單位為毫秒)。  nanosleep(更精確的 POSIX 延時函數)。  std::this_thread::sleep_for(C++11 標準庫,適用于跨平臺)。 延時的精度:usleep 的精度依賴于操作系統調度器。在某些情況下,實際延時可能比指定時間更長,尤其是在多任務系統中。不推薦使用(現代 POSIX):在 POSIX.1-2008 標準中,usleep 已被標記為不推薦使用(deprecated),建議使用更精確的 nanosleep 或 clock_nanosleep。<figure class=""><hr></figure>替代方法(使用 nanosleep):代碼語言:javascript<i class="icon-code"></i>代碼運行次數:<!-- -->0<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewbox="0 0 16 16" fill="none"><path d="M6.66666 10.9999L10.6667 7.99992L6.66666 4.99992V10.9999ZM7.99999 1.33325C4.31999 1.33325 1.33333 4.31992 1.33333 7.99992C1.33333 11.6799 4.31999 14.6666 7.99999 14.6666C11.68 14.6666 14.6667 11.6799 14.6667 7.99992C14.6667 4.31992 11.68 1.33325 7.99999 1.33325ZM7.99999 13.3333C5.05999 13.3333 2.66666 10.9399 2.66666 7.99992C2.66666 5.05992 5.05999 2.66659 7.99999 2.66659C10.94 2.66659 13.3333 5.05992 13.3333 7.99992C13.3333 10.9399 10.94 13.3333 7.99999 13.3333Z" fill="currentcolor"></path></svg>運行<svg width="16" height="16" viewbox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 15.5V3.5H14.5V15.5H4.5ZM12.5 5.5H6.5V13.5H12.5V5.5ZM9.5 2.5H3.5V12.5H1.5V0.5H11.5V2.5H9.5Z" fill="currentcolor"></path></svg>復制<pre class="prism-token token line-numbers javascript">#include <stdio.h>#include <time.h>int main() {    struct timespec ts;    ts.tv_sec = 0;         // 秒    ts.tv_nsec = 50000000; // 納秒(50 毫秒)    printf("Loading... ");    for (int i = 0; i <p>這提供了更高的精度和可靠性。</p> <p>那么到這里我們就能通過下面的代碼進行進度的顯示了</p>代碼語言:javascript<i class="icon-code"></i>代碼運行次數:<!-- -->0<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewbox="0 0 16 16" fill="none"><path d="M6.66666 10.9999L10.6667 7.99992L6.66666 4.99992V10.9999ZM7.99999 1.33325C4.31999 1.33325 1.33333 4.31992 1.33333 7.99992C1.33333 11.6799 4.31999 14.6666 7.99999 14.6666C11.68 14.6666 14.6667 11.6799 14.6667 7.99992C14.6667 4.31992 11.68 1.33325 7.99999 1.33325ZM7.99999 13.3333C5.05999 13.3333 2.66666 10.9399 2.66666 7.99992C2.66666 5.05992 5.05999 2.66659 7.99999 2.66659C10.94 2.66659 13.3333 5.05992 13.3333 7.99992C13.3333 10.9399 10.94 13.3333 7.99999 13.3333Z" fill="currentcolor"></path></svg>運行<svg width="16" height="16" viewbox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 15.5V3.5H14.5V15.5H4.5ZM12.5 5.5H6.5V13.5H12.5V5.5ZM9.5 2.5H3.5V12.5H1.5V0.5H11.5V2.5H9.5Z" fill="currentcolor"></path></svg>復制<pre class="prism-token token line-numbers javascript"> #include"process.h"  2 #include<string.h>  3 #include<unistd.h>  4 #define SIZE 101   5 #define STYLE '#'  6 void process()  7 {  8   //v1版本展示進度條的基本功能  9   int rate=0; 10   //定義一個緩沖區 11   char buffer[SIZE]; 12   memset(buffer,0,sizeof(buffer));//將我們的buffer初始化為0 13   while(rate<figure class=""><img src="https://img.php.cn/upload/article/001/503/042/174487237373236.jpg" alt="深度解析如何在Linux中創建自己的第一個系統程序---進度條"></figure><figure class=""><img src="https://img.php.cn/upload/article/001/503/042/174487237486419.jpg" alt="深度解析如何在Linux中創建自己的第一個系統程序---進度條"></figure><p> 但是我們這個進度條的右側的中擴號不是固定的,而是隨著#的增加而往右邊進行移動的</p> <p>所以我們必須預留出足夠大的空間來進行#的填充操作</p> <p>所以這個右括號不應該隨著進度條的移動而移動</p> <p>我們將代碼改成這樣子,將位置預留出來,然后加上-號向左對齊就行了</p> <figure class=""><img src="https://img.php.cn/upload/article/001/503/042/174487237431499.jpg" alt="深度解析如何在Linux中創建自己的第一個系統程序---進度條"></figure><p> 那么最后我們代碼就完成了</p> <figure class=""><img src="https://img.php.cn/upload/article/001/503/042/174487237486530.jpg" alt="深度解析如何在Linux中創建自己的第一個系統程序---進度條"></figure>代碼語言:javascript<i class="icon-code"></i>代碼運行次數:<!-- -->0<svg xmlns="http://www.w3.org/2000/svg" width="16"    style="max-width:90%" viewbox="0 0 16 16" fill="none"><path d="M6.66666 10.9999L10.6667 7.99992L6.66666 4.99992V10.9999ZM7.99999 1.33325C4.31999 1.33325 1.33333 4.31992 1.33333 7.99992C1.33333 11.6799 4.31999 14.6666 7.99999 14.6666C11.68 14.6666 14.6667 11.6799 14.6667 7.99992C14.6667 4.31992 11.68 1.33325 7.99999 1.33325ZM7.99999 13.3333C5.05999 13.3333 2.66666 10.9399 2.66666 7.99992C2.66666 5.05992 5.05999 2.66659 7.99999 2.66659C10.94 2.66659 13.3333 5.05992 13.3333 7.99992C13.3333 10.9399 10.94 13.3333 7.99999 13.3333Z" fill="currentcolor"></path></svg>運行<svg width="16" height="16" viewbox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 15.5V3.5H14.5V15.5H4.5ZM12.5 5.5H6.5V13.5H12.5V5.5ZM9.5 2.5H3.5V12.5H1.5V0.5H11.5V2.5H9.5Z" fill="currentcolor"></path></svg>復制<pre class="prism-token token line-numbers javascript"> 1 #include"process.h"  2 #include<string.h>  3 #include<unistd.h>  4 #define SIZE 101   5 #define STYLE '#'  6 void process()  7 {  8   //v1版本展示進度條的基本功能  9   int rate=0; 10   //定義一個緩沖區 11   char buffer[SIZE]; 12   memset(buffer,0,sizeof(buffer));//將我們的buffer初始化為0 13   const char*lable="|/-";                                                                                                                                                                    14   int len =strlen(lable); 15  16   while(rate<p>但是這個進度條我們沒辦法直接進行使用的操作</p> <p>我們正常的進度條是隨著這個下載的量而使這個進度條進行增加</p> <p>而不是一次性將這個進度條打完</p> <p>我們這個進度條應該是隨著我們的下載的數據量進行推進的</p> <p>最后的代碼就是這樣的</p> <p>main.c</p>代碼語言:javascript<i class="icon-code"></i>代碼運行次數:<!-- -->0<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewbox="0 0 16 16" fill="none"><path d="M6.66666 10.9999L10.6667 7.99992L6.66666 4.99992V10.9999ZM7.99999 1.33325C4.31999 1.33325 1.33333 4.31992 1.33333 7.99992C1.33333 11.6799 4.31999 14.6666 7.99999 14.6666C11.68 14.6666 14.6667 11.6799 14.6667 7.99992C14.6667 4.31992 11.68 1.33325 7.99999 1.33325ZM7.99999 13.3333C5.05999 13.3333 2.66666 10.9399 2.66666 7.99992C2.66666 5.05992 5.05999 2.66659 7.99999 2.66659C10.94 2.66659 13.3333 5.05992 13.3333 7.99992C13.3333 10.9399 10.94 13.3333 7.99999 13.3333Z" fill="currentcolor"></path></svg>運行<svg width="16" height="16" viewbox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 15.5V3.5H14.5V15.5H4.5ZM12.5 5.5H6.5V13.5H12.5V5.5ZM9.5 2.5H3.5V12.5H1.5V0.5H11.5V2.5H9.5Z" fill="currentcolor"></path></svg>復制<pre class="prism-token token line-numbers javascript">#include"process.h"    2 #include<unistd.h>    3 #include<time.h>    4 #include<stdlib.h>    5 //定義一個函數指針類型    6 typedef void (*call_t)(const char*,double,double);//定義了一個函數指針      的類型    7     8 double total=1024.0;//一共要下載的總量    9 //double speed=1.0;//定義一個網速   10 double speed[]={1.0,0.5,1.2,0.01,0.02};//定義一個網速清單   11    12 //下載   13 //回調函數   14 void download(int total,call_t cb)   15 {   16   srand(time(NULL));   17   double current=0.0;   18   while(current=total) break;   23     //下載代碼   24     int random=rand()%5;   25     usleep(50000);   26    27     current+=speed[random];   28     if(current&gt;=total)                                                   29     {   30       current=total;   31     }   32   }//加上隨機數進行動態的調整操作33 }   34 void uploadload(int total,call_t cb)   35 {   36   srand(time(NULL));   37   double current=0.0;   38   while(current=total) break;   43     //下載代碼   44     int random=rand()%5;   45     usleep(50000);   46    47     current+=speed[random];   48     if(current&gt;=total)   49     {   50       current=total;   51     }   52   }//加上隨機數進行動態的調整操作   53 }   54 int main()E&gt; 55 {   56   download(1024.0,FlushProcess);   57   printf("download 1024.0MB done ");   58   download(512.0,FlushProcess);   59   printf("download 512.0MB done ");   60   download(334.0,FlushProcess);   61   printf("download 334.0MB done ");   62   //process();   63   download(64.0,FlushProcess);   64   printf("download 64.0MB done ");   65   return 0;   66  }</stdlib.h></time.h></unistd.h>

process.c

代碼語言:javascript代碼運行次數:0運行復制

#include"process.h"  2 #include<string.h>  3 #include<unistd.h>  4 #define SIZE 101   5 #define STYLE '#'  6 //v2:根據進度進行動態刷新一次我們的進度條  7 void FlushProcess(const char*tips,double total,double current)  8 {  9   const char*lable="|/-"; 10   int len=strlen(lable); 11   static int index=0;//只要我們調用這整個函數的話,那么我們這個光標就能&gt;    進行轉動的操作了 12   char buffer[SIZE]; 13   memset(buffer,0,sizeof(buffer));//將我們的buffer初始化為0 14                                      15   //int num =(int)(current*100/total);//只要滿足到了1個#的話那么我們就進    行數據的刷新 16   double rate = current*100.0/total; 17   int num=(int)rate;//我們的num直接通過我們的比率進行獲得 18   int i=0;           19   for(;i<num buffer printf fflush index if void process int rate="0;" char memset const len="strlen(lable);" while>    我們的當前行開始輸出,rate%len就是最后顯示的下標只可能是 0 1 2 3這四個數&gt;    ,可以使我們的四個字符一直進行變化的操作 48     fflush(stdout);//將我們緩沖區的消息進行刷新操作 49     buffer[rate]=STYLE; 50     rate++; 51     usleep(50000); 52   } 53   printf(" ");//讓我們左側的命令行新起一行 54 }</num></unistd.h></string.h>

process.h

代碼語言:javascript代碼運行次數:0運行復制

#pragma once    2 #include<stdio.h>  3 //v1版本  4 void process();  5   6 //v2版本  7 //根據當前的量以及總量進行當前進度條的刷新操作  8 void FlushProcess(const char*tips,double total,double current); </stdio.h>

相關閱讀