新聞中心
隨著互聯(lián)網(wǎng)的不斷發(fā)展和技術(shù)的進(jìn)步,操作系統(tǒng)的公司不斷推陳出新,而Linux作為一款自由開(kāi)源、功能強(qiáng)大的操作系統(tǒng),備受開(kāi)發(fā)者和用戶的歡迎。Linux中一個(gè)線程可以使用一個(gè)CPU的所有時(shí)間片,CPU計(jì)算機(jī)的數(shù)量越多,線程數(shù)就能達(dá)到更高的閾值,尤其是對(duì)于多核CPU來(lái)說(shuō),我們可以更加有效地使用多核CPU的優(yōu)勢(shì)。

目前創(chuàng)新互聯(lián)已為上千多家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站托管維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、印臺(tái)網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
然而,隨著線程數(shù)的增加,系統(tǒng)資源的負(fù)載也會(huì)隨之增加。因此,了解如何控制Linux線程數(shù)將有助于我們更好地進(jìn)行系統(tǒng)管理和優(yōu)化。
本文將介紹一些我們可以使用的策略來(lái)控制Linux線程數(shù)。
1.使用ulimit命令
Linux中的ulimit命令可以幫助我們限制一個(gè)進(jìn)程在用戶級(jí)別的資源使用(包括文件打開(kāi)數(shù)量、核心文件大小、進(jìn)程數(shù)量等),這也可以用來(lái)限制線程數(shù)量。您可以使用以下命令來(lái)限制線程數(shù)量:
$ ulimit -u
在這里,-u選項(xiàng)表示限制線程數(shù)。像下面這樣執(zhí)行該命令:
$ ulimit -u 500
這將限制用戶為500個(gè)線程。請(qǐng)注意,該限制將適用于當(dāng)前Shell會(huì)話中運(yùn)行的所有新進(jìn)程和線程。
2.使用cgroups控制組
Linux提供的另一種資源限制機(jī)制是cgroups。cgroups(control groups)是一種在Linux內(nèi)核中實(shí)現(xiàn)的,用于限制、隔離和控制進(jìn)程組的蘑菇。您可以使用cgroups來(lái)限制線程的數(shù)量和使用資源,包括CPU和內(nèi)存的使用情況。
要使用cgroups限制線程數(shù),請(qǐng)按照以下步驟操作:
(a) 首先創(chuàng)建一個(gè)新的控制組,在以下路徑中創(chuàng)建:
$ sudo mkdir /sys/fs/cgroup/thread-limit
(b) 接下來(lái),使用cgroup.controllers文件將控制器分配給線程限制:
$ echo +pids > /sys/fs/cgroup/thread-limit.cgroup.subtree_control
(c) 設(shè)置限制線程數(shù)的值限制,使用以下命令:
$ echo 1000 > /sys/fs/cgroup/thread-limit/pids.max
在這個(gè)例子中,我們限制線程數(shù)為1000。
(d) 使用以下命令為一個(gè)新進(jìn)程啟用控制組:
$ sudo cgexec -g “pids:/thread-limit”
以上命令將在新進(jìn)程中啟用pids控制器,并將控制組分配給/thread-limit。
3.使用/proc/sys/kernel/threads-max文件
Linux還提供了一個(gè)/sys/kernel/threads-max文件,可以用來(lái)設(shè)置系統(tǒng)級(jí)別的線程限制。這個(gè)文件包含一個(gè)數(shù)字,表示可以創(chuàng)建的閾值線程總數(shù)。
要更改線程更大值,請(qǐng)執(zhí)行以下操作:
(a) 使用文本編輯器打開(kāi)/proc/sys/kernel/threads-max文件:
$ sudo vi /proc/sys/kernel/threads-max
(b) 將文件中的數(shù)字更改為所需的更大線程數(shù)。
(c) 保存并關(guān)閉文件。
請(qǐng)注意,更改此值需要root權(quán)限。
:
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗(yàn)豐富以策略為先導(dǎo)10多年以來(lái)專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),響應(yīng)式網(wǎng)站制作,設(shè)計(jì)師量身打造品牌風(fēng)格,熱線:028-86922220Linux中,shell腳本如何使用信號(hào)機(jī)制去控制線程的開(kāi)啟關(guān)閉
trap是Linux的內(nèi)建命令,用于捕捉信號(hào),trap命令可以指定收到某種信號(hào)時(shí)所執(zhí)行的命令。trap命令的格式如下:trap command sig1 sig2 … sigN,當(dāng)接收到sinN中任意一個(gè)信號(hào)時(shí),執(zhí)行command命令,command命令完成后繼續(xù)接收到信號(hào)前的操作,直到腳本結(jié)束。 利用trap命令捕捉INT信號(hào)(即與Ctrl+c綁定的中斷信號(hào))。trap還可以忽略某些信號(hào),將command用空字符串代替即可,如trap “” TERM INT,忽略kill %n和Ctrl+c發(fā)送的信號(hào)(kill發(fā)送的是TERM信號(hào))。Linux更強(qiáng)勁的殺死進(jìn)程的命令:kill -9 進(jìn)程號(hào)(或kill -9 %n作業(yè)號(hào))等價(jià)與kill -KILL 進(jìn)程號(hào)。
舉個(gè)例子
:
最近小A需要生產(chǎn)2023年全年的KPI數(shù)據(jù)報(bào)表,現(xiàn)在小A已經(jīng)將生產(chǎn)腳本猛舉租寫(xiě)好了,生產(chǎn)腳本一次只能生產(chǎn)指定一天的KPI數(shù)據(jù),假設(shè)跑一次生產(chǎn)腳本需要5分鐘,那么:
如果是循環(huán)順序執(zhí)行,那么需要時(shí)間:5 * 365 = 1825 分鐘,約等于 6 天
如果是一次性放到linux后臺(tái)并發(fā)執(zhí)行,365個(gè)后臺(tái)任務(wù),系統(tǒng)可承受不住哦!
既然不能一次性把365個(gè)任務(wù)放到linux后臺(tái)執(zhí)行,那么,能不能實(shí)現(xiàn)自動(dòng)地每次將N個(gè)任務(wù)放到后臺(tái)并發(fā)執(zhí)行呢?當(dāng)然是可以的啦。
#! /bin/bash
source /etc/profile;
#–
tempfifo=$$.fifo# $$表示當(dāng)前執(zhí)行文件的PID
begin_date=$# 開(kāi)始時(shí)間
end_date=$# 結(jié)束時(shí)間
if
then
if “$end_date” >
then
echo “Error! $begin_date is greater than $end_date”
exit 1;
fi
else
echo “Error! Not enough params.”
echo “Sample: sh loop_kpi”
exit 2;
fi
#–
trap “exec 1000>&-;exec 1000$tempfifo
rm -rf $tempfifo
for ((i=1; i&1000
done
while
do
read -u1000
{
echo $begin_date
hive -f kpi_report.sql –hivevar date=$begin_date
echo >&1000
} &
begin_date=`date -d “+1 day $begin_date” +”%Y-%m-%d”`
done
wait
echo “done!!!!!!!!!!”
第6~22行:比如:sh loop_kpi_report.sh:
$1表示腳本入?yún)⒌闹粋€(gè)參數(shù),等于
$2表示腳本入?yún)⒌牡诙€(gè)參數(shù),等于
$#表示腳本入?yún)⒌膫€(gè)數(shù),等于2
第13行用于比較傳入的兩個(gè)日期的大小,\>是轉(zhuǎn)義
第26行:表示在腳本運(yùn)行過(guò)程中,如果接收到Ctrl+C中斷命令,則關(guān)閉文件描述符1000的讀寫(xiě),并正常退出
exec 1000>&-;表示關(guān)閉文件描述符1000的寫(xiě)
exec 1000寫(xiě)的綁定,則標(biāo)識(shí)對(duì)文件描述符1000的所有操作等同于對(duì)管道文件$tempfifo的操作
第29行,可能會(huì)有這樣的枝兆疑問(wèn):為什么不直接使用管道文件呢?事實(shí)上這并非多此一舉,管道的一個(gè)重要特性,就是讀寫(xiě)必須同時(shí)存在,缺失某一個(gè)操作,另一個(gè)操作就是滯留,而第28行的綁定文件描述符(讀、寫(xiě)綁定)正好解決了這個(gè)問(wèn)題
第31~34行:對(duì)文件描述符1000進(jìn)行寫(xiě)入操作。通過(guò)循環(huán)寫(xiě)入8個(gè)空行,這個(gè)8就是我們要定義的后臺(tái)并發(fā)的線程數(shù)。為什么是寫(xiě)空行而不是寫(xiě)其它字符?因?yàn)楣艿牢募淖x取,是以行為單位的
第37~42行:
第37行,read -u1000的作用就是讀取管道中的一行,在這里就是讀取一個(gè)空行;每次讀取管道就會(huì)減少一個(gè)空行
第39~41行,注意到第42行結(jié)尾的&嗎?它表示進(jìn)程放到linux后臺(tái)中執(zhí)行
第41行,執(zhí)行完后臺(tái)任務(wù)之后,往文件描述符1000中寫(xiě)入一個(gè)空行。這是關(guān)鍵所在了,由于read -u1000每次操作,都會(huì)導(dǎo)致管道減少一個(gè)空行,當(dāng)linux后臺(tái)放入了8個(gè)任務(wù)之后,由于文件描述符1000沒(méi)有可讀取的空行,將導(dǎo)致read -u1000一直處于等待。
linux下線程屬性常用操作有哪些
LinuxThread的線程機(jī)制
LinuxThreads是目前Linux平臺(tái)上使用最為廣泛的線程庫(kù),由Xavier Leroy () 負(fù)責(zé)開(kāi)發(fā)完成,并已綁定在GLIBC中發(fā)行。它所實(shí)現(xiàn)的就是基于核心輕量級(jí)進(jìn)程的”一對(duì)一”線程模型,一個(gè)線程實(shí)體對(duì)應(yīng)一個(gè)核心輕量級(jí)進(jìn)程,而線程之間的 管理在核外函數(shù)庫(kù)中實(shí)現(xiàn)。
1.線程描述數(shù)據(jù)結(jié)構(gòu)及實(shí)現(xiàn)限制
LinuxThreads定義了一個(gè)struct _pthread_descr_struct數(shù)據(jù)結(jié)構(gòu)來(lái)描述線程,并使用全局?jǐn)?shù)組變量 __pthread_handles來(lái)描晌胡基述和引用進(jìn)程所轄線程。在__pthread_handles中的前兩項(xiàng),LinuxThreads定義了兩個(gè)全 局的系統(tǒng)線程:__pthread_initial_thread和__pthread_manager_thread,并用 __pthread_main_thread表征__pthread_manager_thread的父線程(初始為 __pthread_initial_thread)。
struct _pthread_descr_struct是一個(gè)雙環(huán)鏈表結(jié)構(gòu),__pthread_manager_thread所在的鏈表僅包括它 一個(gè)元素,實(shí)際上,__pthread_manager_thread是一個(gè)特殊線程,LinuxThreads僅使用了其中的errno、p_pid、 p_priority等三個(gè)域。而__pthread_main_thread所在的鏈則將進(jìn)程中所有用戶線程串在了一起。經(jīng)過(guò)一系列 pthread_create()之后形成的__pthread_handles數(shù)組將如下圖所示:
圖2 __pthread_handles數(shù)組結(jié)構(gòu)
新創(chuàng)建的線程將首先在__pthread_handles數(shù)組中占據(jù)一項(xiàng),然后通過(guò)數(shù)據(jù)結(jié)構(gòu)中的鏈指針連入以__pthread_main_thread為首指針的鏈表中。這個(gè)鏈表的使用在介紹線程的創(chuàng)建和釋放的時(shí)候?qū)⑻岬健?
LinuxThreads遵循POSIX1003.1c標(biāo)準(zhǔn),其中對(duì)線程庫(kù)的實(shí)現(xiàn)進(jìn)行了一些范圍限制,比如進(jìn)程更大線程數(shù),線程私有數(shù)據(jù)區(qū)大小等等。在 LinuxThreads的實(shí)現(xiàn)中,基本遵循這些限制,但也進(jìn)行了一定的改動(dòng),改動(dòng)的趨勢(shì)是放松或者說(shuō)擴(kuò)大這些限制,使編程更加方便。這些限定宏主要集中 在sysdeps/unix/sysv/linux/bits/local_lim.h(不同平臺(tái)使用的文件位置不同)中,包括如下幾個(gè):
每進(jìn)程的私有數(shù)據(jù)key數(shù),POSIX定義_POSIX_THREAD_KEYS_MAX為128,LinuxThreads使用 PTHREAD_KEYS_MAX,1024;私有數(shù)據(jù)釋放時(shí)允許執(zhí)行的操作數(shù),LinuxThreads與POSIX一致,定義 PTHREAD_DESTRUCTOR_ITERATIONS為4;每進(jìn)程的線程數(shù),POSIX定義為64,LinuxThreads增大到1024 (PTHREAD_THREADS_MAX);線程運(yùn)行棧最小空間大小,POSIX未指定,LinuxThreads使用 PTHREAD_STACK_MIN,16384(字節(jié))。
2.管理線程
“一對(duì)一”模型的好處之一是線程的調(diào)度由核心完成了,而其他諸如線程取消、線程間的同步等工作,宴謹(jǐn)都是在核外線程庫(kù)中完成的。在LinuxThreads 中,專門(mén)為每一個(gè)進(jìn)程構(gòu)造了一個(gè)管理線程,負(fù)責(zé)處理線程相關(guān)的管理工作。當(dāng)進(jìn)程之一次調(diào)用pthread_create()創(chuàng)建一個(gè)線程的時(shí)候就會(huì)創(chuàng)建 (__clone())并啟動(dòng)管理線程。
在一個(gè)進(jìn)程空間內(nèi),管理線程與其他線程之間通過(guò)一對(duì)”管理管道(manager_pipe)”來(lái)通訊,該管道在創(chuàng)建管理線程之前創(chuàng)建,在成功啟動(dòng) 了管理線程之后,管理管道的讀端和寫(xiě)端分別做姿賦給兩個(gè)全局變量__pthread_manager_reader和 __pthread_manager_request,之后,每個(gè)用戶線程都通過(guò)__pthread_manager_request向管理線程發(fā)請(qǐng)求, 但管理線程本身并沒(méi)有直接使用__pthread_manager_reader,管道的讀端(manager_pipe)是作為_(kāi)_clone ()的參數(shù)之一傳給管理線程的,管理線程的工作主要就是監(jiān)聽(tīng)管道讀端,并對(duì)從中取出的請(qǐng)求作出反應(yīng)。
創(chuàng)建管理線程的流程如下所示:
(全局變量pthread_manager_request初值為-1)
圖3 創(chuàng)建管理線程的流程
初始化結(jié)束后,在__pthread_manager_thread中記錄了輕量級(jí)進(jìn)程號(hào)以及核外分配和管理的線程id, 2*PTHREAD_THREADS_MAX+1這個(gè)數(shù)值不會(huì)與任何常規(guī)用戶線程id沖突。管理線程作為pthread_create()的調(diào)用者線程的 子線程運(yùn)行,而pthread_create()所創(chuàng)建的那個(gè)用戶線程則是由管理線程來(lái)調(diào)用clone()創(chuàng)建,因此實(shí)際上是管理線程的子線程。(此處子 線程的概念應(yīng)該當(dāng)作子進(jìn)程來(lái)理解。)
__pthread_manager()就是管理線程的主循環(huán)所在,在進(jìn)行一系列初始化工作后,進(jìn)入while(1)循環(huán)。在循環(huán)中,線程以2秒為 timeout查詢(__poll())管理管道的讀端。在處理請(qǐng)求前,檢查其父線程(也就是創(chuàng)建manager的主線程)是否已退出,如果已退出就退出 整個(gè)進(jìn)程。如果有退出的子線程需要清理,則調(diào)用pthread_reap_children()清理。
然后才是讀取管道中的請(qǐng)求,根據(jù)請(qǐng)求類型執(zhí)行相應(yīng)操作(switch-case)。具體的請(qǐng)求處理,源碼中比較清楚,這里就不贅述了。
3.線程棧
在LinuxThreads中,管理線程的棧和用戶線程的棧是分離的,管理線程在進(jìn)程堆中通過(guò)malloc()分配一個(gè)THREAD_MANAGER_STACK_SIZE字節(jié)的區(qū)域作為自己的運(yùn)行棧。
用戶線程的棧分配辦法隨著體系結(jié)構(gòu)的不同而不同,主要根據(jù)兩個(gè)宏定義來(lái)區(qū)分,一個(gè)是NEED_SEPARATE_REGISTER_STACK,這個(gè)屬 性僅在IA64平臺(tái)上使用;另一個(gè)是FLOATING_STACK宏,在i386等少數(shù)平臺(tái)上使用,此時(shí)用戶線程棧由系統(tǒng)決定具置并提供保護(hù)。與此同 時(shí),用戶還可以通過(guò)線程屬性結(jié)構(gòu)來(lái)指定使用用戶自定義的棧。因篇幅所限,這里只能分析i386平臺(tái)所使用的兩種棧組織方式:FLOATING_STACK 方式和用戶自定義方式。
在FLOATING_STACK方式下,LinuxThreads利用mmap()從內(nèi)核空間中分配8MB空間(i386系統(tǒng)缺省的更大??臻g大小,如 果有運(yùn)行限制(rlimit),則按照運(yùn)行限制設(shè)置),使用mprotect()設(shè)置其中之一頁(yè)為非訪問(wèn)區(qū)。該8M空間的功能分配如下圖:
圖4 棧結(jié)構(gòu)示意
低地址被保護(hù)的頁(yè)面用來(lái)監(jiān)測(cè)棧溢出。
對(duì)于用戶指定的棧,在按照指針對(duì)界后,設(shè)置線程棧頂,并計(jì)算出棧底,不做保護(hù),正確性由用戶自己保證。
不論哪種組織方式,線程描述結(jié)構(gòu)總是位于棧頂緊鄰堆棧的位置。
4.線程id和進(jìn)程id
linux運(yùn)行線程數(shù)如何控制器的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux運(yùn)行線程數(shù)如何控制器,如何控制Linux線程數(shù)?,Linux中,shell腳本如何使用信號(hào)機(jī)制去控制線程的開(kāi)啟關(guān)閉,linux下線程屬性常用操作有哪些的信息別忘了在本站進(jìn)行查找喔。
創(chuàng)新互聯(lián)【028-86922220】值得信賴的成都網(wǎng)站建設(shè)公司。多年持續(xù)為眾多企業(yè)提供成都網(wǎng)站建設(shè),成都品牌建站設(shè)計(jì),成都高端網(wǎng)站制作開(kāi)發(fā),SEO優(yōu)化排名推廣服務(wù),全網(wǎng)營(yíng)銷讓企業(yè)網(wǎng)站產(chǎn)生價(jià)值。
分享文章:如何控制Linux線程數(shù)?(linux運(yùn)行線程數(shù)如何控制器)
文章分享:http://fisionsoft.com.cn/article/cdsphpo.html


咨詢
建站咨詢
