⑴ 請問Linux下使用c語言編程如何實現進程的阻塞
你的想法對於單一進程是行不通的,因為一旦進程「阻塞」了,變數的值又怎麼可能自己改變呢?
如果你談的是多進程(或線程),那有很多方法可以使用。但恐怕你不是在進行多進程編程,因為這是多進程編程的最基本概念。如果連這些都未掌握,你根本沒辦法進行下去,更不用設計什麼變數i變數j的了。
⑵ linux系統c語言進程不想被sleep阻塞等待怎麼解決
1、啟動後檯子任務,在執行命令後加&操作符,表示將命令放在子shell中非同步執行。可以達到多線程效果。如下,sleep10#等待10秒,再繼續下一操作sleep10當前shell不等待,後檯子shell等待。
2、wait命令wait是用來阻塞當前進程的執行,直至指定的子進程執行結束後,才繼續執行。使用wait可以在bash腳本「多進程」執行模式下,起到一些特殊控制的作用。
⑶ c語言socket編程中accept的阻塞問題
埠就是負責監聽連接請求的.如果監聽到該埠的請求那麼就可以確定是對你這個伺服器的請求.一旦這個埠被佔用,那麼其它任何程序都無法再使用這個埠.所以我們要避開系統常用埠,要從1024以上的埠選擇.
在伺服器端
sin_port
是不可以被設置為0的,
否則客戶端的確無法連接.
而客戶端可以設置為0,客戶端可以任意埠的,沒有影響.
⑷ c語言如何釋放一個被阻塞住的線程
可以用線程同步機制進行,比如使用CEvent等
可以保留創建的線程指針,使用:
BOOL TerminateThread( HANDLEhThread,DWORDdwExitCode);
⑸ 阻塞隊列,C語言高手來解答,怎麼實現進程阻塞的函數
當然可以,定義成全局變數或者在定義的那個函數返回此隊列把此返回的隊列作為實參傳遞給另一個函數
⑹ 有關C語言編程的題!急!!!
PWM軟體
PWM控制器會產生一連串脈沖。通常需要規定脈沖的周期和寬度。占空比被定義為脈沖寬度與周期的比值。PWM有著廣泛的應用,大多數情況下用於控制模擬電路。因為數字信號連續變化的速率相對較快(當然取決於信號周期),因此最終會形成一個用來控制模擬設備的平均電壓值。當PWM脈沖流應用於馬達時,馬達的轉速就能正比於占空比(從0%到100%)。如果占空比增加,馬達轉速就會提高,反之,如果占空比減小,馬達的轉速隨之也會降低。
用軟體編寫這樣一個PWM控制器是相對比較容易的任務,但它有助於我們簡明扼要地描述如何用Verilog設計硬體。清單1給出了PWM的C代碼。
清單1:完全用軟體實現的位脈沖PWM控制器。
void
pwmTask(uint32_t pulse_width, uint32_t period)
{
uint32_t time_on=pulse_width;
uint32_t time_off=period-pulse_width;
while (1)
{
pwm_output=1;
sleep(time_on);
pwm_output=0;
sleep(time_off);
}
}
根據脈寬(pulse_width)和周期(period)參數值,計算出輸出為高電平和低電平的時間。接下來將輸出引腳置為高電平,並等待time_on設定的時間值之後,將輸出變為低電平,並等待time_off參數設定的時間值。下個周期再重復這樣的過程,並無限循環下去。
Verilog模塊
清單2給出了一個簡單的Verilog模塊,實現帶非同步復位功能的8位寬寄存器。寄存器的輸入「in」在時鍾的上升沿被賦值到輸出「out」,直到clr_n復位信號的下降沿到來(此時輸出將被賦值為0)。
清單2:實現帶非同步復位功能8位寬寄存器的Verilog編寫模塊。
mole simple_register(in, out, clr_n, clk, a);
//埠聲明
input
input
input [7:0]
input
output [7:0]
clr_n;
clk;
in;
a;
out;
//信號聲明
reg [7:0]
wire
out;
a;
//實現帶非同步清除的寄存器
always @(posedge clk or negedge clr_n)
begin
if (clr_n==0) // could also be written if (!clr_n)
out<=0;
else
out<=in;
end
//連續賦值
assign a=!out[0];
endmole
粗略地看Verilog與C語言有許多相似之處。分號用於結束每個語句,注釋符也是相同的(/* ... */和// 都是熟悉的),運算符「==」也用來測試相等性。Verilog的if..then..else語法與C語言的也非常相似,只是Verilog用關鍵字begin和end代替了C的大括弧。事實上,關鍵字begin和end對於單語句塊來說是可有可無的,就與C中的大括弧用法一樣。Verilog和C都對大小寫敏感。
當然,硬體和軟體的一個重要區別是它們的「運行」方式。硬體設計中用到的許多單元都是並行工作的。一旦設備電源開啟,硬體的每個單元就會一直處於運行狀態。雖然根據具體的控制邏輯和數據輸入,設備的一些單元可能不會改變它們的輸出信號,但它們還是一直在「運行」中。
相反,在同一時刻整個軟體設計中只有一小部分(即使是多軟體任務也只有一個任務)在執行。如果只有一個處理器,同一時間點只能有一條指令在執行。軟體的其它部分可以被認為處於休眠狀態,這與硬體有很大的不同。變數可能以一個有效值而存在,但大多數時間里它們都不在使用狀態。
軟硬體的不同行為會直接導致硬體和軟體代碼編程方式的不同。軟體是串列執行的,每一行代碼的執行都要等到前一行代碼執行完畢後才能進行(中斷的非線性或操作系統的命令除外)。
一個Verilog模塊的開頭是關鍵字mole,緊跟其後的是模塊名稱和埠列表,埠列表列出了該模塊用到的所有輸入輸出名稱。接下來是埠聲明部分。注意:所有的輸入輸出既出現在模塊第一行的埠列表中,也會出現在埠聲明(declaration)部分中。
在Verilog中有二種類型的內部信號用得比較多,它們是reg和wire。它們具有不同的功能。所有埠都有一個名稱相同且聲明為wire的信號。因此連線line被聲明為wire不是必要的。reg會保持上次的賦值,因此不需要每次都進行驅動。wire型信號用於非同步邏輯,有時也用來連接信號。因為reg可以保持上次的值,因此輸入不能被聲明為reg類型。在Verilog模塊中可以在任何時候非同步地將輸入改變為任何事件。reg和wire的主要區別是,reg類型的信號只能在過程塊(後面會談到)中賦值,而wire類型的信號只能在過程塊外賦值。這兩種信號類型都可以出現在過程塊內部和外部的賦值運算符右邊。
使用關鍵字reg並不一定意味著編譯器會創建一個寄存器,理解這一點是非常重要的。清單2的代碼中有一個reg類型8位寬的內部信號out。該模塊使用寄存器源於always模塊(過程塊的一種)的編程方式。值得注意的是,信號a是一個wire類型,因此只能在連續賦值(continuous assignment)語句中賦值,而reg類型的out信號只能在always塊中賦值。
always塊是過程塊的一種,僅在某種變化發生時用於更新信號。always語句圓括弧里的表達式組被稱為敏感列表,格式是:(表達式or表達式…)
只要敏感列表中的任何一個表達式值為真,always塊中的代碼就會被執行。Verilog中用於上升沿和下降沿的關鍵字分別是posedge和negedge。這二個關鍵字經常被用於敏感列表。在本例中,如果clk信號的上升沿或clr_n的下降沿信號發生時,always塊內部的語句就會被執行。
為了用好寄存器,輸出必須在時鍾的上升沿得到更新(下降沿也可以,但上升沿更常見些)。增加negedge clr_n會使寄存器在clr_n信號的下降沿復位。但並不是所有的敏感列表都會包含關鍵字posedge或negedge,因此在實際硬體中並不總是存在真實的寄存器。
always塊內的第一條語句判斷clr_n信號的上升沿有沒有發生。如果有,下一行代碼把out置為0。這些代碼行實現了寄存器的非同步復位功能。如果條件語句是:if(negedge clr_n and clk==1),那麼該語句實現的就是基於時鍾的非同步復位。
讀者可能已經注意到,always塊中的賦值運算符與以關鍵字assign開頭的連續賦值語句中用到的運算符不一樣。"<="運算符用於非阻塞性(nonblocking)賦值,而"="運算符用於阻塞性(blocking)賦值。
在一組阻塞性賦值語句中,在下一個阻塞性賦值語句執行前需要計算並賦值第一個賦值語句。這一過程就象C語言中語句的順序執行。而非阻塞語句在執行時,所有賦值語句的右邊被同時計算和賦值。連續賦值語句必須使用阻塞賦值語句(否則編譯器會報錯)。
為了減少代碼出錯的概率,建議在順序邏輯(例如希望以寄存器方式實現的邏輯)always塊中的所有賦值語句使用非阻塞性賦值語句。大多數always塊應該使用非阻塞性賦值語句。如果always塊都是組合邏輯,那麼就需要使用阻塞性賦值語句。
PWM硬體
編寫存儲器映射硬體模塊的首要任務是以軟體方式決定寄存器映射圖。在PWM案例中,一般設計師希望能用軟體設置周期和脈寬。在硬體設計中用計數器統計系統時鍾周期數是非常容易的。因此要用到兩個寄存器,分別命名為pulse_width和period,並且都在時鍾周期內度量。表1給出了PWM的寄存器映射圖。
為了確定輸出信號,硬體可簡單地通過將period和pulse_width寄存器內容作為運行中的計數器保持的輸出。
接下來要為PWM選擇埠,大多數埠可以依據匯流排架構而定。表2提供了通用存儲器映射PWM的信號描述概要。通常為低電平有效的信號命名做法是在信號名上加「_n」,對於控制信號更是如此。表2中的write_n和clr_n信號就是低電平有效的信號(下降沿觸發)。
至此我們已經定義好了硬體模塊的介面,接下來就可以開始編寫Verilog代碼了。清單3給出了一個實現例子。
清單3:用Verilog實現的PWM硬體。
mole pwm (clk, write_data, cs, write_n, addr, clr_n, read_data, pwm_out);
input
input [31:0]
input
input
input
input
output [31:0]
output
clk;
write_data;
cs;
write_n;
addr;
clr_n;
read_data;
pwm_out;
reg [31:0]
reg [31:0]
reg [31:0]
reg
reg [31:0]
wire
period;
pulse_width;
counter;
off;
read_data;
period_en, pulse_width_en; //寫使能
// 定義period和pulse_width寄存器的內容
always @(posedge clk or negedge clr_n)
begin
if (clr_n==0)
begin
period<=32'h 00000000;
pulse_width<=32'h 00000000;
end
else
begin
if (period_en)
period<=write_data[31:0];
else
period<=period;
if (pulse_width_en)
pulse_width<=write_data[31:0];
else
pulse_width<=pulse_width;
end
end
// period和pulse_width寄存器的讀訪問
always @(addr or period or pulse_width)
if (addr == 0)
read_data=period;
else
read_data=pulse_width;
always @(posedge clk or negedge clr_n)
begin
if (clr_n==0)
counter<=0;
else
if (counter>=period-1)
counter<=0;
else
counter<=counter+1;
end
always @(posedge clk or negedge clr_n)
begin
if (clr_n==0)
off<=0;
else
if (counter>=pulse_width)
off <= 1;
else
if (counter==0)
off<=0;
else
off<=off;
end
assign period_en = cs & !write_n & !addr;
assign pulse_width_en = cs & !write_n & addr;
//PWM輸出
assign pwm_out=!off;
endmole
首先是埠說明,接著是內部信號說明。構成PWM軟體控制介面的存儲器映射型寄存器被聲明為reg。該代碼行只允許以32位的方式訪問這些存儲器映射型寄存器。如果需要8位或16位訪問,就必須將寄存器分割成4個8位寄存器,並增加位元組使能信號邏輯。用Verilog代碼實現這一功能是非常簡單的。always塊中已賦過值的所有信號都被聲明為reg類型。聲明為wire類型的信號是period和pulse_width寄存器寫入使能信號。這些信號使用連續賦值語句進行賦值。
⑺ C語言 getch() 為什麼會阻塞,,
getch();並非標准C中的函數,不存在C語言中。!!
所在頭文件:conio.h
建議換成getchar()之類的
getch()
getch():
所在頭文件:conio.h
函數用途:從控制台讀取一個字元,但不顯示在屏幕上
函數原型:int
getch(void)
返回值:讀取的字元
例如:
char
ch;或int
ch;
getch();或ch=getch();
用getch();會等待你按下任意鍵,再繼續執行下面的語句;
用ch=getch();會等待你按下任意鍵之後,把該鍵字元所對應的ASCII碼賦給ch,再執行下面的語句。
易錯點:1.所在頭文件是conio.h。而不是stdio.h。
2.在使用之前要調用initscr(),結束時要調用endwin()。否則會出現不輸入字元這個函數
也會返回的情況。
getch();並非標准C中的函數,不存在C語言中。所以在使用的時候要注意程序的可移植性。國內C語言新手常常使用getch();來暫停程序且不知道此函數來源,建議使用getchar();(如果情況允許)代替此功能或更換一款編譯器。