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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

1线程同步:互斥量,死锁

發(fā)布時間:2024/9/27 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1线程同步:互斥量,死锁 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


1線程為什么要同步

A:共享資源,多個線程都可對共享資源操作。

B:線程操作共享資源的先后順序不確定。

C:處理器對存儲器的操作一般不是原子操作。

2互斥量

mutex操作原語

pthread_mutex_t

pthread_mutex_init

pthread_mutex_destroy

pthread_mutex_lock

pthread_mutex_trylock

pthread_mutex_unlock

3臨界區(qū)(Critical Section

保證在某一時刻只有一個線程能訪問數(shù)據(jù)的簡便辦法。在任意時刻只允許一個線程對共享資源進行訪問。如果有多個線程試圖同時訪問臨界區(qū),那么在有一個線程進入后其他所有試圖訪問此臨界區(qū)的線程將被掛起,并一直持續(xù)到進入臨界區(qū)的線程離開。臨界區(qū)在被釋放后,其他線程可以繼續(xù)搶占,并以此達到用原子方式操作共享資源的目的。

4臨界區(qū)的選定

???臨界區(qū)的選定應(yīng)盡可能小,如果選定太大會影響程序的并行處理性能。

5互斥量實例

依賴的頭文件

#include<pthread.h>

函數(shù)聲明

int pthread_mutex_destroy(pthread_mutex_t*mutex);

名稱:

pthread_mutex_destroy

功能:

釋放對互斥變量分配的資源

頭文件:

#include <pthread.h>

函數(shù)原形:

int? pthread_mutex_destroy(pthread_mutex_t *mutex);

參數(shù):

?

返回值:

若成功則返回0,否則返回錯誤編號。

?

int pthread_mutex_init(pthread_mutex_t*restrict mutex, const pthread_mutexattr_t *restrict attr);

名稱:

pthread_mutexattr_init

功能:

初始化互斥鎖。

頭文件:

#include <pthread.h>

函數(shù)原形:

int pthread_mutex_init(pthread_mutex_t * mutex,

const pthread_mutex_t *attr);

參數(shù):

mutex?互斥量

attr????互斥鎖屬性

返回值:

若成功則返回0,否則返回錯誤編號。

int pthread_mutex_lock(pthread_mutex_t*mutex);

int pthread_mutex_trylock(pthread_mutex_t*mutex);

int pthread_mutex_unlock(pthread_mutex_t*mutex);

名稱:

pthread_mutex_lock/ pthread_mutex_trylock/ pthread_mutex_unlock

功能:

對互斥量加/減鎖

頭文件:

#include <pthread.h>

函數(shù)原形:

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

參數(shù):

?

返回值:

若成功則返回0,否則返回錯誤編號。

函數(shù)說明:

對互斥量進行加鎖,需要調(diào)用pthread_mutex_lock,如果互斥量已經(jīng)上鎖,調(diào)用線程阻塞直至互斥量解鎖。對互斥量解鎖,需要調(diào)用pthread_mutex_unlock.

??????如果線程不希望被阻塞,他可以使用pthread_mutex_trylock嘗試對互斥量進行加鎖。如果調(diào)用pthread_mutex_trylock時互斥量處于未鎖住狀態(tài),那么pthread_mutex_trylock將鎖住互斥量,否則就會失敗,不能鎖住互斥量,而返回EBUSY

?

6互斥鎖創(chuàng)建

有兩種方法創(chuàng)建互斥鎖,靜態(tài)方式和動態(tài)方式。

APOSIX定義了一個宏PTHREAD_MUTEX_INITIALIZER來靜態(tài)初始化互斥鎖,方法如下:

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

B:動態(tài)方式是采用pthread_mutex_init()函數(shù)來初始化互斥鎖,API定義如下:

int pthread_mutex_init(pthread_mutex_t *mutex, constpthread_mutexattr_t *mutexattr);

其中mutexattr用于指定互斥鎖屬性,如果為NULL則使用缺省屬性。

C:pthread_mutex_destroy ()用于注銷一個互斥鎖,API定義如下:

???intpthread_mutex_destroy(pthread_mutex_t *mutex);

D:pthread_mutex_lock()加鎖

E:pthread_mutex_unlock()解鎖

F:pthread_mutex_trylock()測試加鎖

G:釋放內(nèi)存前需要調(diào)用pthread_mutex_destory.

案例說明互斥量加鎖的必要性:

#include<stdio.h>

#include<pthread.h>

#include<stdlib.h>

#include<unistd.h>

?

void *thread_function(void *arg);

/*run_now代表共享資源*/

int run_now = 1;

?

int main(void)

{

???int print_count1 = 0;/*用于循環(huán)控制*/

???pthread_t a_thread;

?

???/*創(chuàng)建一個進程*/

???if(pthread_create(&a_thread,NULL,thread_function,NULL)){

???????perror("Thread creation failed!");

???????exit(1);

???}

?

???while(print_count1++ < 5){

???????/*主線程:如果run_now1就把它修改為2*/

???????if(run_now == 1) {

???????????printf("main thread is run\n");

???????????run_now = 2;

???????} else {

???????????printf("main thread is sleep\n");

???????????sleep(1);

???????}

???}

????????//等待子線程結(jié)束

???pthread_join(a_thread,NULL);

???exit(0);

}

?

void *thread_function(void *arg) {

??int print_count2 = 0;

??while(print_count2++ < 5){

??????if(run_now == 2) /*子線程:如果run_now1就把它修改為1*/

??????{

??????????printf("function thread is run\n");

??????????run_now = 1;

??????}

??????else

??????{

??????????printf("function thread is sleep\n");

??????????sleep(1);

??????}

??}

??pthread_exit(NULL);

}

運行結(jié)果:

現(xiàn)象:main線程和function線程是交替運行的。它們都可以對run_now進行操作。

加鎖后的代碼

#include <stdio.h>

#include <pthread.h>

#include <stdio.h>

#include <stdlib.h>

?

void *thread_function(void *arg);

int run_now=1;?/*run_now代表共享資源*/

pthread_mutex_t work_mutex;?/*定義互斥量*/

?

int main(void) {

???int res;

???int print_count1=0;

???pthread_t a_thread;

?

???if(pthread_mutex_init(&work_mutex,NULL)!=0)?/*初始化互斥量*/

???{

???????perror("Mutex init faied");

???????exit(1);

???}

?

???if(pthread_create(&a_thread,NULL,thread_function,NULL)!=0)?/*創(chuàng)建新線程*/

???{

???????perror("Thread createion failed");

???????exit(1);

???}

?

???if(pthread_mutex_lock(&work_mutex)!=0)?/*對互斥量加鎖*/

???{

???????perror("Lock failed");

???????exit(1);

???} else {

???????printf("main lock\n");

???}

?

???while(print_count1++<5) {

???????if(run_now == 1)?/*主線程:如果run_now1就把它修改為2*/

???????{

???????????printf("main thread is run\n");

???????????run_now=2;

???????} else {

???????????printf("main thread is sleep\n");

???????????sleep(1);

???????}

???}

?

???if(pthread_mutex_unlock(&work_mutex)!=0) /*對互斥量解鎖*/

???{

???????perror("unlock failed");

???????exit(1);

???} else {

???????printf("main unlock\n");

???}

?

???pthread_mutex_destroy(&work_mutex); /*收回互斥量資源*/

???pthread_join(a_thread,NULL); /*等待子線程結(jié)束*/

???exit(0);

}

?

void *thread_function(void *arg) {

???int print_count2=0;

???sleep(1);

?

???if(pthread_mutex_lock(&work_mutex)!=0) {

???????perror("Lock failed");

???????exit(1);

???} else {

???????printf("function lock\n");

???}

???

???while(print_count2++<5) {

???????if(run_now==2)?/*分進程:如果run_now1就把它修改為1*/

???????{

???????????printf("function thread is run\n");

???????????run_now=1;

???????} else {

???????????printf("function thread is sleep\n");

???????????sleep(1);

???????}

???}

?

???if(pthread_mutex_unlock(&work_mutex)!=0)?/*對互斥量解鎖*/

???{

???????perror("unlock failed");

???????exit(1);

???} else {

???????printf("function unlock\n");

???}

???pthread_exit(NULL);

}

運行結(jié)果如下:

總結(jié):從運行結(jié)果可以看到,當主進程把互斥量鎖住后,子進程就不能對共享資源進行操作了,只能是同步的操作了。

#include<stdio.h>

#include<stdlib.h>

#include<pthread.h>

#define NLOOP 5000

?

int counter;

pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

?

void *doit(void *);

?

int main(int argc,char **argv){

???pthread_t tidA,tidB;

?

???pthread_create(&tidA,NULL,doit,NULL);

???pthread_create(&tidB,NULL,doit,NULL);

?

???/*wait for both thread to terminate*/

???pthread_join(tidA,NULL);

???pthread_join(tidB,NULL);

?

???return 0;

}

?

void *doit(void *vptr){

???int i,val;

???for(i = 0;i < NLOOP;i++) {

???????pthread_mutex_lock(&counter_mutex);

???????val = counter;

???????printf("%x:%d\n",(unsigned int) pthread_self(),val + 1);

???????counter = val + 1;

?

???????pthread_mutex_unlock(&counter_mutex);

???}

?

???return NULL;

}

運行結(jié)果:

  • 死鎖

    A同一個線程在擁有A鎖的情況下再次請求獲得A

    B線程一擁有A鎖,請求獲得B鎖;線程二擁有B鎖,請求獲得A鎖,出現(xiàn)死鎖,最終導(dǎo)致的結(jié)果是互相等待。

  • 總結(jié)

    以上是生活随笔為你收集整理的1线程同步:互斥量,死锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。