執行緒安全與可重入函式strtok_r()
一、執行緒安全
一個函式被稱為執行緒安全的(thread-safe),當且僅當被多個併發程序反覆呼叫時,它會一直產生正確的結果。如果一個函式不是執行緒安全的,我們就說它是執行緒不安全的(thread-unsafe)。
例如:
要在主執行緒中根據空格分隔char buff[]=”1 2 3 4 5 6 7 8 9 0”;,並將分隔的資料輸出,每隔1S中分一次,同樣在函式執行緒中分隔char buff[]=”a b c d e f g h i j k”;並將分隔的資料輸出,每隔1S中分一次。
程式碼示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <pthread.h>
void *fun(void *arg)
{
char buff[]="a b c d e f g h i j k";
char *tmp=strtok(buff," ");
while(tmp)
{
printf("%s",tmp);
sleep(1);
tmp=strtok(NULL," ");
}
}
void main()
{
pthread_t th;
int res=pthread_create(&th,NULL,fun,NULL);
assert(res==0);
char buff[]="1 2 3 4 5 6 7 8 9 0";
char *tmp=strtok(buff," ");
while(tmp)
{
printf("%s",tmp);
sleep(1);
tmp=strtok(NULL," ");
}
}
列印結果為:1 a b c d e f g h i g k
分析:列印只打印了 主執行緒中的1,而沒有列印其他字串,是因為字元儲存在棧區,而當函式結束,字元區域會被釋放掉,再進入到主執行緒,傳NULL,沒有字元可分隔,但將函式執行緒的字元分隔,所以應該將字元陣列放到全域性變數區,但是放在全域性變數是不安全的。
所以為了實現全部字元的分割,此處便引進了可重入函式。
二、可重入函式
可重入函式是執行緒安全函式的一種,其特點在於它們被多個執行緒呼叫時,不會引用任何共享資料。
可重入函式通常要比不可重入的執行緒安全函式效率高一些,因為它們不需要同步操作。
1、一個可重入函式需要滿足的是:
a、不使用全域性變數或靜態變數;
b、不使用用malloc或者new開闢出的空間;
c、不呼叫不可重入函式;
d、不返回靜態或全域性資料,所有資料都有函式的呼叫者提供;
e、使用本地資料,或者通過製作全域性資料的本地拷貝來保護全域性資料;
2、不可重入特點
如果一個函式符合以下條件之一的,則是不可重入的:
(1)呼叫了malloc/free函式,因為malloc函式是用全域性連結串列來管理堆的。
(2)呼叫了標準I/O庫函式,標準I/O庫的很多實現都以不可重入的方式使用全域性資料結構。
(3)可重入體內使用了靜態的資料結構。
對於以上問題進行解決:運用strtok_r可重入函。
程式碼示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <pthread.h>
void *fun(void *arg)
{
char buff[]="a b c d e f g h i j k";
char *q=NULL;
char *tmp=strtok_r(buff," ",&q);
while(tmp)
{
printf("%s",tmp);
sleep(1);
tmp=strtok_r(NULL," ",&q);
}
}
void main()
{
pthread_t th;
int res=pthread_create(&th,NULL,fun,NULL);
assert(res==0);
char buff[]="1 2 3 4 5 6 7 8 9 0";
char *q=NULL;
char *tmp=strtok_r(buff," ",&q);
while(tmp)
{
printf("%s",tmp);
sleep(1);
tmp=strtok_r(NULL," ",&q);
}
}
列印結果:a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 0 k;
相關推薦
執行緒安全與可重入函式strtok_r()
一、執行緒安全 一個函式被稱為執行緒安全的(thread-safe),當且僅當被多個併發程序反覆呼叫時,它會一直產生正確的結果。如果一個函式不是執行緒安全的,我們就說它是執行緒不安全的(thread-unsafe)。 例如: 要在主執行緒中根據空格分隔ch
執行緒安全與可重入函式之間的區別
今天,學到了兩個概念。執行緒安全、與可重入函式 這個都是關於多執行緒的,下面我們來看看這兩個概念到底有什麼不同之處。 先來看看這兩個概念 1、什麼是可重入函式 函式被不同的控制流程呼叫,有時會在之前的
關於執行緒安全與可重入函式
一、執行緒安全 一個函式被稱為執行緒安全的,當且僅當被多個併發執行緒反覆地呼叫時,它會一直產生正確的結果。如果一個函式不是執行緒安全的,我們就說它是執行緒不安全的。 四個(不相交的)執行緒不安全函式類
【Linux】執行緒安全與可重入函式
【Linux學習】:在Linux的一段時間學習中,剛開始是模糊的,所以很久沒有進行部落格的整理,直到最近自己把Linux的學習從前往後回憶與聯絡清楚了,覺得是時候整理成部落格,變為自己的學習筆記了,先從執行緒安全和可重入函式整理,一方面是趁熱打鐵,另一方面是在這
對比執行緒安全和可重入函式
1.什麼叫執行緒安全 如果你的程式所在的程序中有多個執行緒在同時執行,而這些執行緒可能同時執行一段程式碼或同時訪問一個物件,如果每次執行完這段程式碼或訪問完這個物件之後,所得到的結果和單執行緒執行的
執行緒安全與可重入
執行緒安全:一個函式被稱為執行緒安全的當且僅當被多個併發執行緒反覆呼叫時,它會一直產生正確的結果。上面已經提到,執行緒不安全的根源在於:共享資料。共享資料可以是:1 函式把返回結果放到一個公共的位置2 由呼叫者傳入的執行緒間共享的指標變數或者引用變數3 函式內部本來就會使用的共享靜態變數任何執行緒不安全問題的
深入理解執行緒安全和可重入函式
執行緒安全 基本定義 執行緒安全:簡單來說執行緒安全就是多個執行緒併發同一段程式碼時,不會出現不同的結果,我們就可以說該執行緒是安全的; 執行緒不安全:說完了執行緒安全,執行緒不安全的問題就很好解
【Linux】執行緒安全以及可重入函式
可重入函式 &emsp函式被不同的控制流程呼叫,有可能在第一次呼叫還沒返回時就再次進入該函式,這稱為重入。 &emsp當程式執行到某一個函式的時候,可能因為硬體中斷或者異常而使得在使用者正在執行的程式碼暫時終端轉而進入你核心,這個時候如有一
線程安全與可重入
計算 一個 線程 數據 變量 -s 安全 函數 safe thread-safe: 如果一個函數在多線程的條件下仍然保持計算結果和單線程一樣,就說明它是線程安全的。 線程安全的函數: 不包含靜態數據區的變量,只有堆棧變量; 有靜態數據區的變量,然而會加鎖; 可重入:
Linux可重入函式和執行緒安全的區別與聯絡(轉)
*****可重入函式 函式被不同的控制流程呼叫,有可能在第一次呼叫還沒返回時就再次進入該函式,這稱為重入。 當程式執行到某一個函式的時候,可能因為硬體中斷或者異常而使得在使用者正在執行的程式
Java多執行緒01_可重入函式、可重入鎖
測試環境 OS:windows7_X64 JDK:jdk1.8.0_20 IDE: eclipse_neon 一、可重入函式 相信很多人都聽說過可重入函式,可重入函式最重要的兩條法則就是: 只
Linux 環境程式設計——淺談可重入函式與不可重入函式
在實時系統的設計中,經常會出現多個任務呼叫同一個函式的情況。如果有一個函式不幸被設計成為這樣:那麼不同任務呼叫這個函式時可能修改其他任務呼叫這個函式的資料,從而導致不可預料的後果。這樣的函式是不安全的函式,也叫不可重入函式。 相反,肯定有一個安全的函式,這個安全的函式又叫可重入函式。那麼什麼是可
Linux系統程式設計——淺談可重入函式與不可重入函式
在實時系統的設計中,經常會出現多個任務呼叫同一個函式的情況。如果有一個函式不幸被設計成為這樣:那麼不同任務呼叫這個函式時可能修改其他任務呼叫這個函式的資料,從而導致不可預料的後果。這樣的函式是不安全的函式,也叫不可重入函式。 相反,肯定有一個安全的函式,這個安全的函式又叫可重入函式。那
Linux:可重入函式與不可重入函式
可重入函式 一個函式在執行的過程中被打斷,然後會再被從頭執行一次,執行完後,再回來把剛才沒執行完的部分執行完。這就相當於巢狀的執行了。函式是公共程式碼,這樣的執行是允許的。函式的執行可以被打斷,打斷之後還可以再從頭執行,執行完後接著執行剛才沒有執行的程式
淺談可重入函式與不可重入函式
在實時系統的設計中,經常會出現多個任務呼叫同一個函式的情況。如果有一個函式不幸被設計成為這樣:那麼不同任務呼叫這個函式時可能修改其他任務呼叫這個函式的資料,從而導致不可預料的後果。這樣的函式是不安全的函式,也叫不可重入函式。 相反,肯定有一個安全的函式,這個安全的函式又叫
可重入函式與不可重入函式概念以及編寫規範
1、定義 一個可重入的函式簡單來說就是可以被中斷的函式,也就是說,可以在這個函式執行的任何時刻中斷它,轉入OS排程下去執行另外一段程式碼,而返回控制時不會出現什麼錯誤;而不可重入的函式由於使用了一些系統資源,比如全域性變數區,中斷向量表等,所以它如果被中斷的話,可能會出現
可重入函式與不可重入函式(轉)
轉自http://www.cnblogs.com/luvi/archive/2008/05/09/1190493.html 主要用於多工環境中,一個可重入的函式簡單來說就是可以被中斷的函式,也就是說,可以在這個函式執行的任何時刻中斷它,轉入OS排程下去執行另外一段程式碼,而返回控制時不會出現什麼錯誤;而不
十二、JVM(HotSpot)執行緒安全與鎖優化----終結篇
注:本博文主要是基於JDK1.7會適當加入1.8內容。 執行緒安全:當多個執行緒訪問一個物件時,如果不用考慮這些執行緒在執行環境下的排程和交替執行,也不需要進行額外的同步,或者在呼叫方進行任何其他的協調操作,呼叫這個物件的行為可以獲取正確的結果,那這個物件就是執行緒安全的。 1、Ja
執行緒安全與效率的問題
執行緒的安全是以犧牲效率為代價的,所謂執行緒安全就是多了個加鎖、解鎖的操作,比如100億個操作中都要加鎖和解鎖,執行緒是安全了,但效率就下降了。而有些軟體是以效率為主的,為了提高效率,就
執行緒安全與非執行緒安全
1、執行緒不共享資料 對同一資源,各個執行緒各自執行一遍,程式碼如下: package com.zzm.th01; /** * 執行緒不共享資料 * Created by ming on 2017/6/15. */ public class th04 extends Thr