當前位置:首頁 » 操作系統 » linux信號量鎖

linux信號量鎖

發布時間: 2023-04-22 17:02:33

linux下信號量和互斥鎖的區別

信號量與互斥鎖之間的區別: 1. 互斥量用於線程的互斥,信號量用於線程的同步。 這是互斥量和信號量的根本區別,也就是互斥和同步之間的區別。 互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。

Ⅱ linux下信號量和互斥鎖的區別

信號量用在多線程多任務同步的,一個線程完成了某一個動作就通過信號量告訴別的線程,別的線程再進行某些動作(大家都在semtake的時候,就阻塞在哪裡)。
而互斥鎖是用在多線程多任務互斥的,一個線程佔用了某一個資源,那麼別的線程就無法訪問,直到這個線程unlock,其他的線程才開始可以利用這個資源。比如對全局變數的訪問,有時要加鎖,操作完了,在解鎖。
有的時候鎖和信號量會同時使用的。我記得以前做的一個項目就是既有semtake,又有lock。

Ⅲ linux 多進程信號同步問題

朋友你好:希望能幫到你。互相學習。
線程的最大特點是資源的共享性,但資源共享中的同步問題是多線程編程的難點。linux下提供了多種方式來處理線程同步,最常用的是互斥鎖、條件變數和信號量。
1)互斥鎖(mutex)
通過鎖機制實現線程間的同步。同一時刻只允許一個線程執行一個關鍵部分的代碼。
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex *mutex);
int pthread_mutex_destroy(pthread_mutex *mutex);
int pthread_mutex_unlock(pthread_mutex *
(1)先初始化鎖init()或靜態賦值pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER
attr_t有:
PTHREAD_MUTEX_TIMED_NP:其餘線程等待隊列
PTHREAD_MUTEX_RECURSIVE_NP:嵌套鎖,允許線程多次加鎖,不同線程,解鎖後重新競爭
PTHREAD_MUTEX_ERRORCHECK_NP:檢錯,與一同,線程請求已用鎖,返回EDEADLK;
PTHREAD_MUTEX_ADAPTIVE_NP:適應鎖,解鎖後重新競爭
(2)加鎖,lock,trylock,lock阻塞等待鎖,trylock立即返回EBUSY
(3)解鎖,unlock需滿足是加鎖狀態,且由加鎖線程解鎖
(4)清除鎖,destroy(此時鎖必需unlock,否則返回EBUSY,//Linux下互斥鎖不佔用內存資源
示例代碼
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
#include "iostream"
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int tmp;
void* thread(void *arg)
{
cout << "thread id is " << pthread_self() << endl;
pthread_mutex_lock(&mutex);
tmp = 12;
cout << "Now a is " << tmp << endl;
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
pthread_t id;
cout << "main thread id is " << pthread_self() << endl;
tmp = 3;

cout << "In main func tmp = " << tmp << endl;
if (!pthread_create(&id, NULL, thread, NULL))
{
cout << "Create thread success!" << endl;
}
else
{
cout << "Create thread failed!" << endl;
}
pthread_join(id, NULL);
pthread_mutex_destroy(&mutex);

return 0;
}
編譯: g++ -o thread testthread.cpp -lpthread
說明:pthread庫不是Linux系統默認的庫,連接時需要使用靜態庫libpthread.a,所以在使用pthread_create()創建線程,以及調用pthread_atfork()函數建立fork處理程序時,需要鏈接該庫。在編譯中要加 -lpthread參數。
2)條件變數(cond)
利用線程間共享的全局變數進行同步的一種機制。條件變數上的基本操作有:觸發條件(當條件變為 true 時);等待條件,掛起線程直到其他線程觸發條件。
int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond); //解除所有線程的阻塞
(1)初始化.init()或者pthread_cond_t cond=PTHREAD_COND_INITIALIER(前者為動態初始化,後者為靜態初始化);屬性置為NULL
(2)等待條件成立.pthread_wait,pthread_timewait.wait()釋放鎖,並阻塞等待條件變數為真,timewait()設置等待時間,仍未signal,返回ETIMEOUT(加鎖保證只有一個線程wait)
(3)激活條件變數:pthread_cond_signal,pthread_cond_broadcast(激活所有等待線程)
(4)清除條件變數:destroy;無線程等待,否則返回EBUSY
對於
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
一定要在mutex的鎖定區域內使用。
如果要正確的使用pthread_mutex_lock與pthread_mutex_unlock,請參考
pthread_cleanup_push和pthread_cleanup_pop宏,它能夠在線程被cancel的時候正確的釋放mutex!
另外,posix1標准說,pthread_cond_signal與pthread_cond_broadcast無需考慮調用線程是否是mutex的擁有者,也就是說,可以在lock與unlock以外的區域調用。如果我們對調用行為不關心,那麼請在lock區域之外調用吧。
說明:
(1)pthread_cond_wait 自動解鎖互斥量(如同執行了pthread_unlock_mutex),並等待條件變數觸發。這時線程掛起,不佔用CPU時間,直到條件變數被觸發(變數為ture)。在調用 pthread_cond_wait之前,應用程序必須加鎖互斥量。pthread_cond_wait函數返回前,自動重新對互斥量加鎖(如同執行了pthread_lock_mutex)。
(2)互斥量的解鎖和在條件變數上掛起都是自動進行的。因此,在條件變數被觸發前,如果所有的線程都要對互斥量加鎖,這種機制可保證在線程加鎖互斥量和進入等待條件變數期間,條件變數不被觸發。條件變數要和互斥量相聯結,以避免出現條件競爭——個線程預備等待一個條件變數,當它在真正進入等待之前,另一個線程恰好觸發了該條件(條件滿足信號有可能在測試條件和調用pthread_cond_wait函數(block)之間被發出,從而造成無限制的等待)。
(3)pthread_cond_timedwait 和 pthread_cond_wait 一樣,自動解鎖互斥量及等待條件變數,但它還限定了等待時間。如果在abstime指定的時間內cond未觸發,互斥量mutex被重新加鎖,且pthread_cond_timedwait返回錯誤 ETIMEDOUT。abstime 參數指定一個絕對時間,時間原點與 time 和 gettimeofday 相同:abstime = 0 表示 1970年1月1日00:00:00 GMT。
(4)pthread_cond_destroy 銷毀一個條件變數,釋放它擁有的資源。進入 pthread_cond_destroy 之前,必須沒有在該條件變數上等待的線程。
(5)條件變數函數不是非同步信號安全的,不應當在信號處理程序中進行調用。特別要注意,如果在信號處理程序中調用 pthread_cond_signal 或pthread_cond_boardcast 函數,可能導致調用線程死鎖。
示常式序1
#include <stdio.h>

#include <pthread.h>

#include "stdlib.h"

#include "unistd.h"
pthread_mutex_t mutex;

pthread_cond_t cond;
void hander(void *arg)

{

free(arg);

(void)pthread_mutex_unlock(&mutex);

}
void *thread1(void *arg)

{

pthread_cleanup_push(hander, &mutex);

while(1)

{

printf("thread1 is running\n");

pthread_mutex_lock(&mutex);

pthread_cond_wait(&cond,&mutex);

printf("thread1 applied the condition\n");

pthread_mutex_unlock(&mutex);

sleep(4);

}

pthread_cleanup_pop(0);

}
void *thread2(void *arg)

{

while(1)

{

printf("thread2 is running\n");

pthread_mutex_lock(&mutex);

pthread_cond_wait(&cond,&mutex);

printf("thread2 applied the condition\n");

pthread_mutex_unlock(&mutex);

sleep(1);

}

}
int main()

{

pthread_t thid1,thid2;

printf("condition variable study!\n");

pthread_mutex_init(&mutex,NULL);

pthread_cond_init(&cond,NULL);

pthread_create(&thid1,NULL,thread1,NULL);

pthread_create(&thid2,NULL,thread2,NULL);

sleep(1);

do

{

pthread_cond_signal(&cond);

}while(1);

sleep(20);

pthread_exit(0);

return 0;

}
示常式序2:
#include <pthread.h>

#include <unistd.h>

#include "stdio.h"

#include "stdlib.h"
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
struct node

{

int n_number;

struct node *n_next;

} *head = NULL;
/*[thread_func]*/

static void cleanup_handler(void *arg)

{

printf("Cleanup handler of second thread./n");

free(arg);

(void)pthread_mutex_unlock(&mtx);

}
static void *thread_func(void *arg)

{

struct node *p = NULL;

pthread_cleanup_push(cleanup_handler, p);

while (1)

{

//這個mutex主要是用來保證pthread_cond_wait的並發性

pthread_mutex_lock(&mtx);

while (head == NULL)

{

//這個while要特別說明一下,單個pthread_cond_wait功能很完善,為何

//這里要有一個while (head == NULL)呢?因為pthread_cond_wait里的線

//程可能會被意外喚醒,如果這個時候head != NULL,則不是我們想要的情況。

//這個時候,應該讓線程繼續進入pthread_cond_wait

// pthread_cond_wait會先解除之前的pthread_mutex_lock鎖定的mtx,

//然後阻塞在等待對列里休眠,直到再次被喚醒(大多數情況下是等待的條件成立

//而被喚醒,喚醒後,該進程會先鎖定先pthread_mutex_lock(&mtx);,再讀取資源

//用這個流程是比較清楚的/*block-->unlock-->wait() return-->lock*/

pthread_cond_wait(&cond, &mtx);

p = head;

head = head->n_next;

printf("Got %d from front of queue/n", p->n_number);

free(p);

}

pthread_mutex_unlock(&mtx); //臨界區數據操作完畢,釋放互斥鎖

}

pthread_cleanup_pop(0);

return 0;

}
int main(void)

{

pthread_t tid;

int i;

struct node *p;

//子線程會一直等待資源,類似生產者和消費者,但是這里的消費者可以是多個消費者,而

//不僅僅支持普通的單個消費者,這個模型雖然簡單,但是很強大

pthread_create(&tid, NULL, thread_func, NULL);

sleep(1);

for (i = 0; i < 10; i++)

{

p = (struct node*)malloc(sizeof(struct node));

p->n_number = i;

pthread_mutex_lock(&mtx); //需要操作head這個臨界資源,先加鎖,

p->n_next = head;

head = p;

pthread_cond_signal(&cond);

pthread_mutex_unlock(&mtx); //解鎖

sleep(1);

}

printf("thread 1 wanna end the line.So cancel thread 2./n");
//關於pthread_cancel,有一點額外的說明,它是從外部終止子線程,子線程會在最近的取消點,退出

//線程,而在我們的代碼里,最近的取消點肯定就是pthread_cond_wait()了。

pthread_cancel(tid);

pthread_join(tid, NULL);

printf("All done -- exiting/n");

return 0;

}
3)信號量
如同進程一樣,線程也可以通過信號量來實現通信,雖然是輕量級的。
信號量函數的名字都以"sem_"打頭。線程使用的基本信號量函數有四個。
#include <semaphore.h>
int sem_init (sem_t *sem , int pshared, unsigned int value);
這是對由sem指定的信號量進行初始化,設置好它的共享選項(linux 只支持為0,即表示它是當前進程的局部信號量),然後給它一個初始值VALUE。
兩個原子操作函數:
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
這兩個函數都要用一個由sem_init調用初始化的信號量對象的指針做參數。
sem_post:給信號量的值加1;
sem_wait:給信號量減1;對一個值為0的信號量調用sem_wait,這個函數將會等待直到有其它線程使它不再是0為止。
int sem_destroy(sem_t *sem);
這個函數的作用是再我們用完信號量後都它進行清理。歸還自己佔有的一切資源。
示例代碼:
#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <pthread.h>

#include <semaphore.h>

#include <errno.h>
#define return_if_fail(p) if((p) == 0){printf ("[%s]:func error!/n", __func__);return;}
typedef struct _PrivInfo

{

sem_t s1;

sem_t s2;

time_t end_time;

}PrivInfo;

static void info_init (PrivInfo* thiz);
static void info_destroy (PrivInfo* thiz);

static void* pthread_func_1 (PrivInfo* thiz);

static void* pthread_func_2 (PrivInfo* thiz);
int main (int argc, char** argv)

{

pthread_t pt_1 = 0;

pthread_t pt_2 = 0;

int ret = 0;

PrivInfo* thiz = NULL;
thiz = (PrivInfo* )malloc (sizeof (PrivInfo));

if (thiz == NULL)

{

printf ("[%s]: Failed to malloc priv./n");

return -1;

}
info_init (thiz);
ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, thiz);

if (ret != 0)

{

perror ("pthread_1_create:");

}
ret = pthread_create (&pt_2, NULL, (void*)pthread_func_2, thiz);

if (ret != 0)

{

perror ("pthread_2_create:");

}
pthread_join (pt_1, NULL);

pthread_join (pt_2, NULL);

info_destroy (thiz);
return 0;
}
static void info_init (PrivInfo* thiz)

{

return_if_fail (thiz != NULL);
thiz->end_time = time(NULL) + 10;
sem_init (&thiz->s1, 0, 1);

sem_init (&thiz->s2, 0, 0);
return;

}
static void info_destroy (PrivInfo* thiz)

{

return_if_fail (thiz != NULL);
sem_destroy (&thiz->s1);

sem_destroy (&thiz->s2);
free (thiz);

thiz = NULL;
return;

}
static void* pthread_func_1 (PrivInfo* thiz)

{

return_if_fail (thiz != NULL);
while (time(NULL) < thiz->end_time)

{

sem_wait (&thiz->s2);

printf ("pthread1: pthread1 get the lock./n");
sem_post (&thiz->s1);

printf ("pthread1: pthread1 unlock/n");
sleep (1);

}
return;

}
static void* pthread_func_2 (PrivInfo* thiz)

{

return_if_fail (thiz != NULL);
while (time (NULL) < thiz->end_time)

{

sem_wait (&thiz->s1);

printf ("pthread2: pthread2 get the unlock./n");
sem_post (&thiz->s2);

printf ("pthread2: pthread2 unlock./n");
sleep (1);

}
return;

}
通 過執行結果後,可以看出,會先執行線程二的函數,然後再執行線程一的函數。它們兩就實現了同步

Ⅳ 求助:linux 用戶態 線程同步中信號量,互斥

你好,
1.信號量和自旋鎖一般都用於互斥.
2.信號量一般進行上下文切換,可休眠,但不可中斷.
3.自旋鎖可中斷(中斷臨界區無獲鎖操作),不可休眠.
4.信號量互斥,一般臨界區TIME(sem)較長; 自旋鎖,一般臨界區TIME(lock)較短.

Ⅳ Linux信號量

信號量是包含一個非負整數型的變數,並且帶有兩個原子操作wait和signal。Wait還可以被稱為down、P或lock,signal還可以被稱為up、V、unlock或post。在UNIX的API中(POSIX標准)用的是wait和post。

對於wait操作,如果信號量的非負整形變數S大於0,wait就將其減1,如果S等於0,wait就將調用線程阻塞;對於post操作,如果有線程在信號量上阻塞(此時S等於0),post就會解除對某個等待線程的阻塞,使其從wait中返回,如果沒有線程阻塞在信號量上,post就將S加1.

由此可見,S可以被理解為一種資源的數量,信號量即是通過控制這種資源的分配來實現互斥和同步的。如果把S設為1,那麼信號量即可使多線程並發運行。另外,信號量不僅允許使用者申請和釋放資源,而且還允許使用者創造資源,這就賦予了信號量實現同步的功能。可見信號量的功能要比互斥量豐富許多。

POSIX信號量是一個sem_t類型的變數,但POSIX有兩種信號量的實現機制: 無名信號量 命名信號量 。無名信號量只可以在共享內存的情況下,比如實現進程中各個線程之間的互斥和同步,因此無名信號量也被稱作基於內存的信號量;命名信號量通常用於不共享內存的情況下,比如進程間通信。

同時,在創建信號量時,根據信號量取值的不同,POSIX信號量還可以分為:

下面是POSIX信號量函數介面:

信號量的函數都以sem_開頭,線程中使用的基本信號函數有4個,他們都聲明在頭文件semaphore.h中,該頭文件定義了用於信號量操作的sem_t類型:

【sem_init函數】:

該函數用於創建信號量,原型如下:

該函數初始化由sem指向的信號對象,設置它的共享選項,並給它一個初始的整數值。pshared控制信號量的類型,如果其值為0,就表示信號量是當前進程的局部信號量,否則信號量就可以在多個進程間共享,value為sem的初始值。

該函數調用成功返回0,失敗返回-1。

【sem_destroy函數】:

該函數用於對用完的信號量進行清理,其原型如下:

成功返回0,失敗返回-1。

【sem_wait函數】:

該函數用於以原子操作的方式將信號量的值減1。原子操作就是,如果兩個線程企圖同時給一個信號量加1或減1,它們之間不會互相干擾。其原型如下:

sem指向的對象是sem_init調用初始化的信號量。調用成功返回0,失敗返回-1。

sem_trywait()則是sem_wait()的非阻塞版本,當條件不滿足時(信號量為0時),該函數直接返回EAGAIN錯誤而不會阻塞等待。

sem_timedwait()功能與sem_wait()類似,只是在指定的abs_timeout時間內等待,超過時間則直接返回ETIMEDOUT錯誤。

【sem_post函數】:

該函數用於以原子操作的方式將信號量的值加1,其原型如下:

與sem_wait一樣,sem指向的對象是由sem_init調用初始化的信號量。調用成功時返回0,失敗返回-1。

【sem_getvalue函數】:

該函數返回當前信號量的值,通過restrict輸出參數返回。如果當前信號量已經上鎖(即同步對象不可用),那麼返回值為0,或為負數,其絕對值就是等待該信號量解鎖的線程數。

【實例1】:

【實例2】:

之所以稱為命名信號量,是因為它有一個名字、一個用戶ID、一個組ID和許可權。這些是提供給不共享內存的那些進程使用命名信號量的介面。命名信號量的名字是一個遵守路徑名構造規則的字元串。

【sem_open函數】:

該函數用於創建或打開一個命名信號量,其原型如下:

參數name是一個標識信號量的字元串。參數oflag用來確定是創建信號量還是連接已有的信號量。

oflag的參數可以為0,O_CREAT或O_EXCL:如果為0,表示打開一個已存在的信號量;如果為O_CREAT,表示如果信號量不存在就創建一個信號量,如果存在則打開被返回,此時mode和value都需要指定;如果為O_CREAT|O_EXCL,表示如果信號量存在則返回錯誤。

mode參數用於創建信號量時指定信號量的許可權位,和open函數一樣,包括:S_IRUSR、S_IWUSR、S_IRGRP、S_IWGRP、S_IROTH、S_IWOTH。

value表示創建信號量時,信號量的初始值。

【sem_close函數】:

該函數用於關閉命名信號量:

單個程序可以用sem_close函數關閉命名信號量,但是這樣做並不能將信號量從系統中刪除,因為命名信號量在單個程序執行之外是具有持久性的。當進程調用_exit、exit、exec或從main返回時,進程打開的命名信號量同樣會被關閉。

【sem_unlink函數】:

sem_unlink函數用於在所有進程關閉了命名信號量之後,將信號量從系統中刪除:

【信號量操作函數】:

與無名信號量一樣,操作信號量的函數如下:

命名信號量是隨內核持續的。當命名信號量創建後,即使當前沒有進程打開某個信號量,它的值依然保持,直到內核重新自舉或調用sem_unlink()刪除該信號量。

無名信號量的持續性要根據信號量在內存中的位置確定:

很多時候信號量、互斥量和條件變數都可以在某種應用中使用,那這三者的差異有哪些呢?下面列出了這三者之間的差異:

Ⅵ 簡述Linux進程間通信的幾種方式

進程間通訊進程間通信就是不同進程之間傳播或交換信息,進程的用戶空間是互相獨立的,進程之間可以利用系統空間交換信息。
管道(pipe)管道是一種半雙工的通信方式,數據只能單向流動。如果要進行雙工通信,需要建立兩個管道。
管道只能在具有親緣關系的進程間使用,例如父子進程或兄弟進程。
有名管道(named
pipe)
有名管道也是雙半工的通信方式,但它允許無親緣關系的進程間使用。
信號量(semophore)
信號量常用來作為一種鎖機制來使用,它是一個記數器,用來控制多進程對共享資源的訪問,防止多個進程同時訪問一個共享資源。信號量主要用作為進程間或同一進程間不同線程之間的同步手段。
信號(sinal)
信號是一種比較復雜的通信方式,用於通知接收進程某些事件已經發生,要注意信號處理中調用的函數是否為信號安全。
消息隊列(message
queue)
消息隊列是由消息的鏈表組成,存放在內核中並由消息隊列標識符標識。
共享內存(shared
memory)
共享內存就是映射一段被其他進程所訪問的內存,這段共享內存由一個進程創建,可由多個進程訪問。共享內存是最快的IPC方式,它是針對其他進程間通信方式的低運行效率而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
套接字(socket)
套接字也是進程間通信的一種方式,與其他方式不同的是,它可以用在不同主機間的進程通信(也是它的主要用途)。
幾種方式的缺點
管道:
速度慢,容量有限,只能用於親緣關系進程間通信。
有名管道:
同管道,不過允許無親緣關系進程間通信。
消息隊列:
容量受系統限制,隊列中會遺留數據,讀時要考慮到這些未讀完的數據。
信號量:
主要用於同步,無法傳遞復雜的數據信息。

Ⅶ Linux進程間通信(互斥鎖、條件變數、讀寫鎖、文件鎖、信號燈)

為了能夠有效的控制多個進程之間的溝通過程,保證溝通過程的有序和和諧,OS必須提供一定的同步機制保證進程之間不會自說自話而是有效的協同工作。比如在 共享內存的通信方式中,兩個或者多個進程都要對共享的內存進行數據寫入,那麼怎麼才能保證一個進程在寫入的過程中不被其它的進程打斷,保證數據的完整性 呢?又怎麼保證讀取進程在讀取數據的過程中數據不會變動,保證讀取出的數據是完整有效的呢?

常用的同步方式有: 互斥鎖、條件變數、讀寫鎖、記錄鎖(文件鎖)和信號燈.

互斥鎖:

顧名思義,鎖是用來鎖住某種東西的,鎖住之後只有有鑰匙的人才能對鎖住的東西擁有控制權(把鎖砸了,把東西偷走的小偷不在我們的討論范圍了)。所謂互斥, 從字面上理解就是互相排斥。因此互斥鎖從字面上理解就是一點進程擁有了這個鎖,它將排斥其它所有的進程訪問被鎖住的東西,其它的進程如果需要鎖就只能等待,等待擁有鎖的進程把鎖打開後才能繼續運行。 在實現中,鎖並不是與某個具體的變數進行關聯,它本身是一個獨立的對象。進(線)程在有需要的時候獲得此對象,用完不需要時就釋放掉。

互斥鎖的主要特點是互斥鎖的釋放必須由上鎖的進(線)程釋放,如果擁有鎖的進(線)程不釋放,那麼其它的進(線)程永遠也沒有機會獲得所需要的互斥鎖。

互斥鎖主要用於線程之間的同步。

條件變數:

上文中提到,對於互斥鎖而言,如果擁有鎖的進(線)程不釋放鎖,其它進(線)程永遠沒機會獲得鎖,也就永遠沒有機會繼續執行後續的邏輯。在實際環境下,一 個線程A需要改變一個共享變數X的值,為了保證在修改的過程中X不會被其它的線程修改,線程A必須首先獲得對X的鎖。現在假如A已經獲得鎖了,由於業務邏 輯的需要,只有當X的值小於0時,線程A才能執行後續的邏輯,於是線程A必須把互斥鎖釋放掉,然後繼續「忙等」。如下面的偽代碼所示:

1.// get x lock

2.while(x

Ⅷ Linux信號 機制和Linux信號量機制的區別

首先,一句話總結它們之間的區別:

字面上相似,但是本質上存在巨大的差別!請看詳細解答...
Linux信號(signal) 機制

signal,又簡稱為信號(軟中斷信號)用來通知進程發生了非同步事件。

原理:

一個進程收到一個信號與處理器收到一個中斷請求可以說是一樣的。信號是進程間通信機制中唯一的非同步通信機制,一個進程不必通過任何操作來等待信號的到達,事實上,進程也不知道信號到底什麼時候到達。進程之間可以互相通過系統調用kill發送軟中斷信號。內核也可以因為內部事件而給進程發送信號,通知進程發生了某個事件。信號機制除了基本通知功能外,還可以傳遞附加信息。

分類:
從兩個不同的分類角度對信號進行:
可靠性方面:可靠信號與不可靠信號;
與時間的關繫上:實時信號與非實時信號。

部分定義轉自:http://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html

Linux信號量(semaphore)機制
Linux內核的信號量用來操作系統進程間同步訪問共享資源。

原理:信號量在創建時需要設置一個初始值,表示同時可以有幾個任務可以訪問該信號量保護的共享資源,初始值為1就變成互斥鎖(Mutex),即同時只能有一個任務可以訪問信號量保護的共享資源。
一個任務要想訪問共享資源,首先必須得到信號量,獲取信號量的操作將把信號量的值減1,若當前信號量的值為負數,表明無法獲得信號量,該任務必須掛起在該信號量的等待隊列等待該信號量可用;若當前信號量的值為非負數,表示可以獲得信號量,因而可以立刻訪問被該信號量保護的共享資源。
當任務訪問完被信號量保護的共享資源後,必須釋放信號量,釋放信號量通過把信號量的值加1實現,如果信號量的值為非正數,表明有任務等待當前信號量,因此它也喚醒所有等待該信號量的任務。

常用的信號量的API:

DECLARE_MUTEX(name)

該宏聲明一個信號量name並初始化它的值為0,即聲明一個互斥鎖。
DECLARE_MUTEX_LOCKED(name)

該宏聲明一個互斥鎖name,但把它的初始值設置為0,即鎖在創建時就處在已鎖狀態。因此對於這種鎖,一般是先釋放後獲得。
void sema_init (struct semaphore *sem, int val);

該函用於數初始化設置信號量的初值,它設置信號量sem的值為val。
void init_MUTEX (struct semaphore *sem);

該函數用於初始化一個互斥鎖,即它把信號量sem的值設置為1。
void init_MUTEX_LOCKED (struct semaphore *sem);

該函數也用於初始化一個互斥鎖,但它把信號量sem的值設置為0,即一開始就處在已鎖狀態。
void down(struct semaphore * sem);

該函數用於獲得信號量sem,它會導致睡眠,因此不能在中斷上下文(包括IRQ上下文和softirq上下文)使用該函數。該函數將把sem的值減1,如果信號量sem的值非負,就直接返回,否則調用者將被掛起,直到別的任務釋放該信號量才能繼續運行。
int down_interruptible(struct semaphore * sem);

該函數功能與down類似,不同之處為,down不會被信號(signal)打斷,但down_interruptible能被信號打斷,因此該函數有返回值來區分是正常返回還是被信號中斷,如果返回0,表示獲得信號量正常返回,如果被信號打斷,返回-EINTR。
int down_trylock(struct semaphore * sem);

該函數試著獲得信號量sem,如果能夠立刻獲得,它就獲得該信號量並返回0,否則,表示不能獲得信號量sem,返回值為非0值。因此,它不會導致調用者睡眠,可以在中斷上下文使用。
void up(struct semaphore * sem);

該函數釋放信號量sem,即把sem的值加1,如果sem的值為非正數,表明有任務等待該信號量,因此喚醒這些等待者。

實例:
信號量在絕大部分情況下作為互斥鎖使用,下面以console驅動系統為例說明信號量的使用。

在內核源碼樹的kernel/printk.c中,使用宏DECLARE_MUTEX聲明了一個互斥鎖console_sem,它用於保護console驅動列表console_drivers以及同步對整個console驅動系統的訪問。

Ⅸ linux mutex互斥體和semaphore信號量的區別

  1. mutex保護的資源在同一時刻只允許一個task進行訪問;semaphore根據初始值n可以允許至多n個task訪問。

  2. semaphore可以實現「等待」機制,一種常見的場景是task0進入阻塞狀態「等待」某個事件發生,task1觸發事件後「喚醒」task0。task0在「等待」時處於阻塞狀態而不是運行狀態,因此不會浪費CPU時間。而一個task在拿到mutex之後釋放之前不宜進行太長時間的操作,更不能阻塞。

Ⅹ Linux 中有名信號量,異常關閉其他線程如何獲取

linux下進程間同步的機制有以下三種:
信號量
記錄鎖(文件鎖)
共享內存中的mutex
效率上 共享內存mutex > 信號量 > 記錄鎖
posix 提供了新的信號量 - 有名信號量,既可以使用在進程間同步也可以作為線程間同步的手段。效率比共享內存mutex要好一些

熱點內容
鳥存儲空氣 發布:2025-05-18 00:20:24 瀏覽:200
linux刻錄iso 發布:2025-05-18 00:16:15 瀏覽:661
php動態參數 發布:2025-05-18 00:12:05 瀏覽:425
安卓應用上傳 發布:2025-05-18 00:11:57 瀏覽:802
數對的演算法 發布:2025-05-18 00:11:02 瀏覽:381
linuxwhile 發布:2025-05-18 00:10:08 瀏覽:143
xpftp外網 發布:2025-05-17 23:58:11 瀏覽:385
如何評價一個伺服器的性能 發布:2025-05-17 23:40:53 瀏覽:270
淘寶客適合什麼伺服器 發布:2025-05-17 23:39:26 瀏覽:613
python循環文件 發布:2025-05-17 23:39:22 瀏覽:829