Linux系統編程---8(全局變量異步I/O,可重入函數)

全局變量異步 I/O

分析如下父子進程交替 數數 程序。當捕捉函數里面的 sleep 取消,程序即會出現問題。請分析原因。

#include<stdio.h> 
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>intn=0,flag=0; void  sys_err(char*   str) 
{ perror(str); exit(1); 
} 
void	do_sig_child	(int	num) 
{printf("I	am	child %d\t%d\n",getpid(),n);n+=2;flag=1; sleep(1); 
} 
void	do_sig_parent	(int	num)
{printf("I	am	parent%d\t%d\n",getpid(),n);n+=2;flag=1;sleep(1); 
} 
int	main(void) {pid_tpid;
struct	sigaction	act;
if((pid=fork())<0)sys_err("fork");else	if(pid>0){n=1;sleep(1);act.sa_handler	=	do_sig_parent; sigemptyset(&act.sa_mask); act.sa_flags=0;sigaction(SIGUSR2,&act,NULL); //注冊自己的信號捕捉函數 父使用 SIGUSR2 信號 do_sig_parent(0); while(1){ /*waitforsignal*/;if(flag==1){ //父進程數數完成 kill(pid,SIGUSR1);flag=0; //標志已經給子進程發送完信號 } } }else	if(pid==0){ n=2;act.sa_handler	=	do_sig_child; sigemptyset(&act.sa_mask); act.sa_flags=0; sigaction(SIGUSR1,&act,NULL);while(1){ /*waitingforasignal*/;if	(flag==1)	{kill(getppid(),SIGUSR2); flag=0; } }}return0; 
}

示例中,通過 flag 變量標記程序實行進度。flag 置 1 表示數數完成。flag 置 0 表示給對方發送信號完成。 問題出現的位置,在父子進程 kill 函數之后需要緊接著調用 flag,將其置 0,標記信號已經發送。但,在這期 間很有可能被 kernel 調度,失去執行權利,而對方獲取了執行時間,通過發送信號回調捕捉函數,從而修改了全局 的 flag。
如何解決該問題呢?可以使用后續課程講到的“鎖”機制。當操作全局變量的時候,通過加鎖、解鎖來解決該 問題。
現階段,我們在編程期間如若使用全局變量,應在主觀上注意全局變量的異步 IO 可能造成的問題。
有兩個進程對同一個變量進行操作。

可/不可重入函數

一個函數在被調用執行期間(尚未調用結束),由于某種時序又被重復調用,稱之為“重入”。根據函數實現的方 法可分為“可重入函數”和“不可重入函數”兩種

例如:
在這里插入圖片描述

顯然,insert 函數是不可重入函數,重入調用,會導致意外結果呈現。究其原因,是該函數內部實現使用了全 局變量

注意事項

  1. 定義可重入函數,函數內不能含有全局變量及 static 變量,不能使用 malloc、free
  2. 信號捕捉函數應設計為可重入函數
  3. 信號處理程序可以調用的可重入函數可參閱 man7signal
  4. 沒有包含在上述列表中的函數大多是不可重入的,其原因為:
    a) 使用靜態數據結構
    b) 調用了 malloc 或 free
    c) 是標準 I/O 函數

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

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

相關文章

http使用post上傳文件時,請求頭和主體信息總結

請求頭必須配置如下行&#xff1a; Content-Type : multipart/form-data; boundary---12321 boundary---12321位文件的分界線 body如下&#xff1a; "-----12321\r\n" //分割文件時加-- "Content-Disposition: form-data; name\"…

iconv 文件編碼轉換

iconv 文件編碼轉換 http://qq164587043.blog.51cto.com/261469/63349 linux shell 配置文件中默認的字符集編碼為UTF&#xff0d;8 。UTF&#xff0d;8是unicode的一種表達方式&#xff0c;gb2312是和unicode都是字符的編碼方式&#xff0c;所以說gb2312跟utf&#xff0d;8的…

Linu系統編程---9(SIGCHLD 信號,信號傳參,中斷系統調用)

SIGCHLD 信號 SIGCHLD 的產生條件 子進程終止時子進程接收到 SIGSTOP 信號停止時子進程處在停止態&#xff0c;接受到 SIGCONT 后喚醒時 借助 SIGCHLD 信號回收子進程 子進程結束運行&#xff0c;其父進程會收到 SIGCHLD 信號。該信號的默認處理動作是忽略。可以捕捉該信號…

Linu系統編程---10(Linux的終端,線路規程,網絡終端,進程組)

終端 輸入輸出設備的總稱 在 UNIX 系統中&#xff0c;用戶通過終端登錄系統后得到一個 Shell 進程&#xff0c;這個終端成為 Shell 進程的控制終端&#xff08;Controlling Terminal&#xff09;&#xff0c; 進程中&#xff0c;控制終端是保存在 PCB 中的信息&#xff0c;而 …

PCRE函數簡介和使用示例

PCRE是一個NFA正則引擎&#xff0c;不然不能提供完全與Perl一致的正則語法功能。但它同時也實現了DFA&#xff0c;只是滿足數學意義上的正則。 PCRE提供了19個接口函數&#xff0c;為了簡單介紹&#xff0c;使用PCRE內帶的測試程序(pcretest.c)示例用法。 1. pcre_compile 原型…

Linux系統編程---11(會話,守護進程,創建守護進程)

會話 創建會話 創建一個會話需要注意以下6點注意事項 調用進程不能是進程組組長&#xff0c;該進程變成新會話首進程該進程成為一個新進程組的組長進程需要root權限&#xff08;nbuntu不需要&#xff09;新會話丟棄原有的控制終端&#xff0c;該會話沒有控制終端該調用進程是…

判斷一段文件是UTF-8編碼還是GB2312的編碼方式

分類&#xff1a; 算法 cpp2012-03-10 16:01 7120人閱讀 評論(2) 收藏 舉報null生活c對于只包含中文和英文的文本中判斷編碼方式是非常簡單的&#xff0c;中文的編碼方式最常用的是GBK&#xff0c;字符集更大的如GBK向下兼容GB2312&#xff0c;其中包含的的很多一部分字符是我們…

判斷文件的編碼方式

/*功能&#xff1a;實現文件編碼格式的判斷通過一個文件的最前面三個字節&#xff0c;可以判斷出該的編碼類型&#xff1a;ANSI&#xff1a;        無格式定義&#xff1b;(第一個字節開始就是文件內容)Unicode&#xff1a;       前兩個字節為FFFE&#xff1b;…

Linux系統編程----12(線程概念,Linux線程實現原理,棧中ebp指針和ebp指針,線程的優缺點和共享資源)

線程概念 什么是線程 在一個程序里的一個執行路線就叫做線程&#xff08;thread&#xff09;。更準確的定義是&#xff1a;線程是“一個進程內部的控制序列” 一切進程至少都有一個執行線程線程在進程內部運行&#xff0c;本質是在進程地址空間內運行在Linux系統中&#xff0…

Linux系統編程---13(線程控制函數,創建線程,循環創建多個線程,線程間共享全局變量)

線程控制 操作系統并沒有提供創建線程的系統調用接口&#xff0c;因此大佬們封裝了一個線程的接口庫實現線程控制。意為著用戶創建線程都使用的是庫函數&#xff08;所以有時候我們說創建的線程是一個用戶態線程&#xff0c;但是在內核中對應有一個輕量級進程實現線程程序的調…

Linux系統編程---14(回收子線程,回收多個子線程,線程分離,殺死線程)

回收子線程 pthread_join 函數 阻塞等待線程退出&#xff0c;獲取線程退出狀態 其作用&#xff0c;對應進程中 waitpid() 函數。 int pthread_join (pthread_t thread,void** retval); 成功&#xff1a;0&#xff0c;失敗&#xff1a;錯誤號 參數&#xff1a;thread&#x…

Linux系統編程----15(線程與進程函數之間的對比,線程屬性及其函數,線程屬性控制流程,線程使用注意事項,線程庫)

對比 進程 線程 fork pthread_create exit (10) pthread_exit &#xff08;void *&#xff09; wait (int *) pthread_join &#xff08;&#xff0c;void **&#xff09;阻塞 kill pthread_cancel ();必須到取消點&#xff08;檢查點&#xff09;&#xff1a;…

內核雙向循環鏈表

#include <string.h>#include <stdio.h>#include <stdlib.h>#include<malloc.h>#include <arpa/inet.h>//鏈表頭結構struct list_head{struct list_head *next,*prev;};//真正實現鏈表插入操作void _list_add(struct list_head *nnew,struct lis…

Linux系統編程----16(線程同步,互斥量 mutex,互斥鎖的相關函數,死鎖,讀寫鎖)

同步概念 所謂同步&#xff0c;即同時起步&#xff0c;協調一致。不同的對象&#xff0c;對“同步”的理解方式略有不同。如&#xff0c;設備同步&#xff0c;是指在兩 個設備之間規定一個共同的時間參考&#xff1b;數據庫同步&#xff0c;是指讓兩個或多個數據庫內容保持一致…

轉移字符的轉換

使得網頁上不會顯示 \x0a\x0a \x0a \x0a \x0a \x0a 類似的字符static int te_escape_isDec(char *ptr, unsigned int len) { …

Linux系統編程---17(條件變量及其函數,生產者消費者條件變量模型,生產者與消費者模型(線程安全隊列),條件變量優點,信號量及其主要函數,信號量與條件變量的區別,)

條件變量 條件變量本身不是鎖&#xff01;但它也可以造成線程阻塞。通常與互斥鎖配合使用。給多線程提供一個會合的場所。 主要應用函數&#xff1a; pthread_cond_init 函數pthread_cond_destroy 函數pthread_cond_wait 函數pthread_cond_timedwait 函數pthread_cond_signa…

好友

http://blog.csdn.net/liangyuannao/article/details/8583139

Linux系統編程---18(線程池相關概念及其實現)

線程池 概念&#xff1a; 一堆線程任務隊列 作用 避免大量線程頻繁的創建/銷毀時間成本避免瞬間大量線程創建耗盡資源&#xff0c;程序崩潰危險 實現 創建固定數量的線程創建一個線程安全的任務隊列 一種線程使用模式。 線程過多會帶來調度開銷&#xff0c;進而影響緩…

設計模式--1(設計模式基礎,設計模式基本原則,設計模式分類)

設計模式基礎 模式 在一定環境中解決某一問題的方案&#xff0c;包括三個基本元素–問題&#xff0c;解決方案和環境。大白話&#xff1a;在一定環境下&#xff0c;用固定套路解決問題。 設計模式 是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使…

source insight 使用技巧

source insight 使用技巧 1 sourceinsight screen font 的默認字體是Verdana的&#xff0c;它是一直變寬字體。在Document style中可以將字體改為定寬的Courier2 document options->auto indent 去掉indent Open Brace和Indent Close Brace的效果: 繼上一段&#xff0c;在…