導航:首頁 > 操作系統 > 線程鎖linuxc

線程鎖linuxc

發布時間:2022-07-06 07:29:44

linux C里線程未加鎖線程可以對全局變數做運算操作嗎

可以 啊 。線程就是數據的共享啊。全局變數的訪問 。

㈡ linux內核線程死鎖或死循環之後如何讓系統宕機重啟

在開發內核模塊或驅動時,如果處理失誤,導致內核線程中出現死鎖或者死循環,你會發現,除了重啟之外,你沒有任何可以做的。這時你的輸入不起任何作用,終端(不是指遠程的ssh工具)只會在那重復的輸出類似「BUG: soft lockup - CPU#0 stuck for 67s! [fclustertool:2043]」,更無奈的是你重啟之後導致系統掛起的堆棧信息也看不到,你所能做的就是一遍遍的加調試信息,一遍遍的重啟機器(這是我的經歷,現在想想很傻)。 這種情況你肯定不是第一個遇到的,所以內核肯定會提供處理這種情況的一些機制。但是如何來找到這些機制在哪個地方,或者說根據什麼信息去google呢?最有用的就是這句話「BUG: soft lockup - CPU#0 stuck for 67s! [fclustertool:2043]」,因為這句話提供你的信息量很大。首先,這條信息可以輸出,說明即使發生死鎖或者死循環,還是有代碼可以執行。第二,可以通過這個日誌信息,找到對應的處理函數,這個函數所在的模塊就是用來處理CPU被過度使用時用到的。所以通過這個事情,可以看到內核列印出的只言片語都有可能成為你解決問題的關鍵,一定要從重視這些信息,從中找出有用的東西。 我經常看的內核版本是官方的2.6.32內核,這個版本中我找到的函數是softlockup_tick(),這個函數在時鍾中斷的處理函數run_local_timers()中調用。這個函數會首先檢查watchdog線程是否被掛起,如果不是watchdog線程,會檢查當前佔有CPU的線程佔有的時間是否超過系統配置的閾值,即softlockup_thresh。如果當前佔有CPU的時間過長,則會在系統日誌中輸出我們上面看到的那條日誌。接下來才是最關鍵的,就是輸出模塊信息、寄存器信息和堆棧信息,檢查softlockup_panic的值是否為1。如果softlockup_panic為1,則調用panic()讓內核掛起,輸出OOPS信息。代碼如下所示:/** This callback runs from the timer interrupt, and checks * whether the watchdog thread has hung or not:*/void softlockup_tick(void){int this_cpu = smp_processor_id(); unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu); unsigned long print_timestamp; struct pt_regs *regs = get_irq_regs(); unsigned long now; /* Warn about unreasonable delays: */ if (now <= (touch_timestamp + softlockup_thresh))return; per_cpu(print_timestamp, this_cpu) = touch_timestamp; spin_lock(&print_lock); printk(KERN_ERR BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n, this_cpu, now - touch_timestamp, current-comm, task_pid_nr(current)); print_moles(); print_irqtrace_events(current);if (regs)show_regs(regs);elsemp_stack(); spin_unlock(&print_lock); if (softlockup_panic) panic(softlockup: hung tasks);} 但是softlockup_panic的值默認竟然是0,所以在出現死鎖或者死循環的時候,會一直只輸出日誌信息,而不會宕機,這個真是好坑啊!所以你得手動修改/proc/sys/kernel/softlockup_panic的值,讓內核可以在死鎖或者死循環的時候可以宕機。如果你的機器中安裝了kmp,在重啟之後,你會得到一份內核的core文件,這時從core文件中查找問題就方便很多了,而且再也不用手動重啟機器了。如果你的內核是標准內核的話,可以通過修改/proc/sys/kernel/softlockup_thresh來修改超時的閾值,如果是CentOS內核的話,對應的文件是/proc/sys/kernel/watchdog_thresh。CentOS內核和標准內核還有一個地方不一樣,就是處理CPU佔用時間過長的函數,CentOS下是watchdog_timer_fn()函數。 這里介紹下lockup的概念。lockup分為soft lockup和hard lockup。 soft lockup是指內核中有BUG導致在內核模式下一直循環的時間超過10s(根據實現和配置有所不同),而其他進程得不到運行的機會。hard softlockup是指內核已經掛起,可以通過watchdog這樣的機制來獲取詳細信息。這兩個概念比較類似。如果你想了解更多關於lockup的信息,可以參考這篇文檔: 注意上面說的這些,都是在內核線程中有效,對用戶態的死循環沒用。如果要監視用戶態的死循環,或者內存不足等資源的情況,強烈推薦軟體層面的watchdog。具體的操作可以參考下面的文章,都寫的非常好,非常實用:

㈢ 線程鎖的原理是什麼

線程鎖的原理:當對象獲取鎖時,它首先使自己的高速緩存無效,這樣就可以保證直接從主內存中裝入變數。

同樣,在對象釋放鎖之前,它會刷新其高速緩存,強制使已做的任何更改都出現在主內存中。 這樣,會保證在同一個鎖上同步的兩個線程看到在 synchronized 塊內修改的變數的相同值。

一般來說,線程以某種不必讓其他線程立即可以看到的方式(不管這些線程在寄存器中、在處理器特定的緩存中,還是通過指令重排或者其他編譯器優化),不受緩存變數值的約束。

(3)線程鎖linuxc擴展閱讀:

線程鎖在run()函數中使用QMutex實現同步,當多個線程訪問共享變數時,使用lock/trylock和unlock將共享變數包裹,以保證同步訪問共享變數。

如果不加鎖將會在2秒後同時修改num變數,將會導致線程不按照我們的想法執行,當前線程鎖定後,其他線程如果遇到共享變數將會等待解鎖;

使用QMutex上鎖解鎖時,當代碼提前退出有可能並未執行unlock(),若其他線程採用lock上鎖會一直被阻塞,導致內存溢出。

㈣ 在linux中用C語言實現死鎖

讓我來告訴你答案!設置狀態變數lock=0,在佔用資源的函數中,設置lock=1;並在處理結束後設lock=0.
比如:
boollock=0;
intscan()
{
while(lock!=0);//循環檢測,直到資源釋放才執行下面的語句
lock=1;//鎖定資源
...//具體的執行掃描的語句
lock=1;//釋放資源
return0;
}
這個方法容易實現,但是佔用CPU,假定其他線程正在佔用掃描儀,那麼這個線程就會在自己的時間片內不停的執行while語句直到對方釋放掃描儀。由此造成了浪費。
現在流行的做法是通過中斷信號來做,那是一本書的內容,建議看linux內核編程方面的書。

㈤ Linux C 怎麼實現兩個線程同步讀取兩個內存的數據

在Linux系統中使用C/C++進行多線程編程時,我們遇到最多的就是對同一變數的多線程讀寫問題,大多情況下遇到這類問題都是通過鎖機制來處理,但這對程序的性能帶來了很大的影響,當然對於那些系統原生支持原子操作的數據類型來說,我們可以使用原子操作來處理,這能對程序的性能會得到一定的提高。那麼對於那些系統不支持原子操作的自定義數據類型,在不使用鎖的情況下如何做到線程安全呢?本文將從線程局部存儲方面,簡單講解處理這一類線程安全問題的方法。

一、數據類型
在C/C++程序中常存在全局變數、函數內定義的靜態變數以及局部變數,對於局部變數來說,其不存在線程安全問題,因此不在本文討論的范圍之內。全局變數和函數內定義的靜態變數,是同一進程中各個線程都可以訪問的共享變數,因此它們存在多線程讀寫問題。在一個線程中修改了變數中的內容,其他線程都能感知並且能讀取已更改過的內容,這對數據交換來說是非常快捷的,但是由於多線程的存在,對於同一個變數可能存在兩個或兩個以上的線程同時修改變數所在的內存內容,同時又存在多個線程在變數在修改的時去讀取該內存值,如果沒有使用相應的同步機制來保護該內存的話,那麼所讀取到的數據將是不可預知的,甚至可能導致程序崩潰。
如果需要在一個線程內部的各個函數調用都能訪問、但其它線程不能訪問的變數,這就需要新的機制來實現,我們稱之為Static memory local to a thread (線程局部靜態變數),同時也可稱之為線程特有數據(TSD: Thread-Specific Data)或者線程局部存儲(TLS: Thread-Local Storage)。這一類型的數據,在程序中每個線程都會分別維護一份變數的副本(),並且長期存在於該線程中,對此類變數的操作不影響其他線程。如下圖:

二、一次性初始化
在講解線程特有數據之前,先讓我們來了解一下一次性初始化。多線程程序有時有這樣的需求:不管創建多少個線程,有些數據的初始化只能發生一次。列如:在C++程序中某個類在整個進程的生命周期內只能存在一個實例對象,在多線程的情況下,為了能讓該對象能夠安全的初始化,一次性初始化機制就顯得尤為重要了。——在設計模式中這種實現常常被稱之為單例模式(Singleton)。Linux中提供了如下函數來實現一次性初始化:
#include <pthread.h>

// Returns 0 on success, or a positive error number on error
int pthread_once (pthread_once_t *once_control, void (*init) (void));
利用參數once_control的狀態,函數pthread_once()可以確保無論有多少個線程調用多少次該函數,也只會執行一次由init所指向的由調用者定義的函數。init所指向的函數沒有任何參數,形式如下:
void init (void)
{
// some variables initializtion in here
}
另外,參數once_control必須是pthread_once_t類型變數的指針,指向初始化為PTHRAD_ONCE_INIT的靜態變數。在C++0x以後提供了類似功能的函數std::call_once (),用法與該函數類似。使用實例請參考https://github.com/ApusApp/Swift/blob/master/swift/base/singleton.hpp實現。

㈥ linux 如何查看是否有線程死鎖

linux和windows不一樣,好像沒有真正意義上的線程吧,應該是進程模擬的 用這個命令可以看: ps -ef f

㈦ Linux 多線程 死鎖問題求解

這么專業的問題還是不要在這問了,白費時間和精力!本人的多線程死鎖還一直是個難題,再加上socket通訊的阻塞與非阻塞,非常不好辦。
網上也就解決點常識性的,別的還是需要閉門造車的精神多做研究吧

㈧ 關於linux 線程互斥鎖的問題,到底怎麼鎖的

首先初始化的鎖為全局變數,為所有線程共享,你一個線程得到鎖後自然而然就將其他線程阻塞了嘛,解鎖後其他線程才能獲取鎖,理解哪個鎖是一個阻塞性函數就ok,何必糾結呢,具體深挖掘的話就可以參照Linux環境高級編程了!

㈨ linux c 中 errno 是怎麼實現線程間的互斥的

你的意思是指線程間對errno這個變數互斥?那就對所有會設置errno的函數調用加鎖丫.咔咔!但是這樣做效率得多低呀....所以,不要對errno互斥.咔咔!

㈩ linux線程同步的互斥鎖(mutex)到底怎麼用的》謝謝

互斥鎖(mutex) 通過鎖機制實現線程間的同步。

1、初始化鎖。在Linux下,線程的互斥量數據類型是pthread_mutex_t。在使用前,要對它進行初始化。

2、靜態分配:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

3、動態分配:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);

4、加鎖。對共享資源的訪問,要對互斥量進行加鎖,如果互斥量已經上了鎖,調用線程會阻塞,直到互斥量被解鎖。

intpthread_mutex_lock(pthread_mutex*mutex);
intpthread_mutex_trylock(pthread_mutex_t*mutex);
解鎖。在完成了對共享資源的訪問後,要對互斥量進行解鎖。
intpthread_mutex_unlock(pthread_mutex_t*mutex);
銷毀鎖。鎖在是使用完成後,需要進行銷毀以釋放資源。
intpthread_mutex_destroy(pthread_mutex*mutex);
#include<cstdio>
#include<cstdlib>
#include<unistd.h>
#include<pthread.h>
#include"iostream"
usingnamespacestd;
pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;
inttmp;
void*thread(void*arg)
{
cout<<"threadidis"<<pthread_self()<<endl;
pthread_mutex_lock(&mutex);
tmp=12;
cout<<"Nowais"<<tmp<<endl;
pthread_mutex_unlock(&mutex);
returnNULL;
}
intmain()
{
pthread_tid;
cout<<"mainthreadidis"<<pthread_self()<<endl;
tmp=3;
cout<<"Inmainfunctmp="<<tmp<<endl;
if(!pthread_create(&id,NULL,thread,NULL))
{
cout<<"Createthreadsuccess!"<<endl;
}
else
{
cout<<"Createthreadfailed!"<<endl;
}
pthread_join(id,NULL);
pthread_mutex_destroy(&mutex);
return0;
}
//編譯:g++-othreadtestthread.cpp-lpthread
閱讀全文

與線程鎖linuxc相關的資料

熱點內容
python軟體功能簡介 瀏覽:784
外國程序員一般多少歲退休 瀏覽:917
怎麼看linux和時間伺服器 瀏覽:680
程序員搞笑花名 瀏覽:501
dota2怎麼設置國服伺服器地址 瀏覽:212
單片機高電平驅動 瀏覽:115
ios多選文件夾 瀏覽:909
加強行車調度命令管理 瀏覽:243
伺服器已禁用什麼意思 瀏覽:150
部隊命令回復 瀏覽:755
神奇寶貝伺服器地圖怎麼設置 瀏覽:382
加密演算法輸出固定長度 瀏覽:862
程序員去重慶還是武漢 瀏覽:121
伺服器如何撤銷網頁登錄限制 瀏覽:980
微信公眾平台php開發視頻教程 瀏覽:628
怎麼看蘋果授權綁定的app 瀏覽:255
壓縮機單級壓縮比 瀏覽:380
linux測試php 瀏覽:971
什麼時候梁旁邊需要加密箍筋 瀏覽:40
微信清粉軟體源碼 瀏覽:717