日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux线程——线程安全问题

發布時間:2024/4/17 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux线程——线程安全问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線程安全即就是在多線程運行的時候,不論線程的調度順序怎樣,最終的結果都是一樣的、正確的。那么就說這些線程是安全的。
要保證線程安全需要做到:
(1) 對線程同步,保證同一時刻只有一個線程訪問臨界資源。
(2)在多線程中使用線程安全的函數(可重入函數),所謂線程安全的函數指的是:如果一個函數能被多個線程同時調用且不發生竟態條件,則我們程它是線程安全的。
可重入函數:就是輸入一定的情況下,輸出結果必然固定,而且從邏輯上講要正確,不受任何其他情況的影響。所以可重入函數不能用全局變量、靜態變量。
我們期待這樣一件事情,主線程對字符串進行分割,子線程對字符串也進行分割,然后進行輸出。unsave.c代碼:

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #include<unistd.h> #include<pthread.h>void* pthread_fun(void* arg) {char buff[] = "a b c d e f g h i j k";char* p = strtok(buff," ");while(p != NULL){printf("fun:%s\n",p);p = strtok(NULL," ");sleep(1);}pthread_exit(NULL); }int main() {pthread_t id;int res = pthread_create(&id,NULL,pthread_fun,NULL);assert(res == 0);char buff[] = "1 2 3 4 5 6 7 8 9 10";char *p = strtok(buff," ");while(p != NULL){printf("main:%s\n",p);p = strtok(NULL," ");sleep(1);}char* s = NULL;pthread_join(id,(void**)s);exit(0); }

運行結果:

為什么會出現這種結果呢?原因就出在strtok中。我們知道strtok分割字符串,下次會從上次分割的地方繼續往后分割,它怎么知道上次分割到哪了呢?指針!每次分割完,指針都會指向分割的結束點,作為下次分割的開始點,而這個指針是一個靜態變量,比如一開始主線程先分割,分割完之后,指針指向2,線程pthread_fun開始分割,分割完又叫這個指針指向b,以記錄下次分割開始點,再往后,兩個線程就繼續都從b開始往后分割了,直至把字符串分割完,進程結束。
那么解決方法呢?加鎖行嗎?不行。因為問題出在strtok內部,出在那個指針上,而且就一個指針,沒辦法加鎖解決。所以strtok這個函數,不適合用在多線程中。所以系統又提供了一個線程安全的版本strtok_r(char* str, const char* delim, char**saveptr)。saveptr是我們自己傳入一個指針地址,用我們傳入的指針來記錄分割結束(開始)點。
修改后的save.c代碼如下:

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #include<unistd.h> #include<pthread.h>void* pthread_fun(void* arg) {char buff[] = "a b c d e f g h i j k";char* q = NULL;char* p = strtok_r(buff," ",&q);while(p != NULL){printf("fun:%s\n",p);p = strtok_r(NULL," ",&q);sleep(1);}pthread_exit(NULL); }int main() {pthread_t id;int res = pthread_create(&id,NULL,pthread_fun,NULL);assert(res == 0);char buff[] = "1 2 3 4 5 6 7 8 9 10";char *q = NULL;char *p = strtok_r(buff," ",&q);while(p != NULL){printf("main:%s\n",p);p = strtok_r(NULL," ",&q);sleep(1);}char* s = NULL;pthread_join(id,(void**)s);exit(0); }

運行結果:

總結

以上是生活随笔為你收集整理的Linux线程——线程安全问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。