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

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


咨詢
建站咨詢
