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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

openmp 互斥锁 mysql_OpenMP(四)线程同步之互斥锁函数

發布時間:2023/12/14 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 openmp 互斥锁 mysql_OpenMP(四)线程同步之互斥锁函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線程同步之互斥鎖函數

前文介紹了互斥鎖同步的兩種方法:atomic和critical,本章介紹OpenMP提供的互斥鎖函數。互斥鎖函數類似于Windows、Linux下的mutex。

1. 互斥鎖函數

函數聲明?????????????????????????????????????????????????????????????????? 功能

void omp_init_lock(omp_lock*)?????????????????????????????? 初始化互斥器

void omp_destroy_lock(omp_lock*)??????????????????????? 銷毀互斥器

void omp_set_lock(omp_lock*)?????????????????????????????? 獲得互斥器

void omp_unset_lock(omp_lock*)?????????????????????????? 釋放互斥器

void omp_test_lock(omp_lock*)????????????????????????????? 試圖獲得互斥器,如果獲得成功則返回true,否則返回false

2. 互斥鎖示例

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

#include?

#include?

static?omp_lock_t?lock;

int?main()

{

omp_init_lock(&lock);?//初始化互斥鎖

#pragma?omp?parallel?for

for(int?i?=?0;?i?

{

omp_set_lock(&lock);???//獲得互斥器

std::cout?<

std::cout?<

omp_unset_lock(&lock);?//釋放互斥器

}

omp_destroy_lock(&lock);??//銷毀互斥器

return?0;

}

#include

#include

static omp_lock_t lock;

int main()

{

omp_init_lock(&lock); //初始化互斥鎖

#pragma omp parallel for

for(int i = 0; i < 5; ++i)

{

omp_set_lock(&lock); //獲得互斥器

std::cout << omp_get_thread_num() << "+" << std::endl;

std::cout << omp_get_thread_num() << "-" << std::endl;

omp_unset_lock(&lock); //釋放互斥器

}

omp_destroy_lock(&lock); //銷毀互斥器

return 0;

}

上邊的示例對for循環中的所有內容進行加鎖保護,同時只能有一個線程執行for循環中的內容。

線程1或線程2在執行for循環內部代碼時不會被打斷。如果刪除代碼中的獲得鎖釋放鎖的代碼,則相當于沒有互斥鎖。

互斥鎖函數中只有omp_test_lock函數是帶有返回值的,該函數可以看作是omp_set_lock的非阻塞版本。

線程同步之事件同步機制

1. 引言

前邊已經提到,線程的同步機制包括互斥鎖同步和事件同步。互斥鎖同步包括atomic、critical、mutex函數,其機制與普通多線程同步的機制類似。而事件同步則通過nowait、sections、single、master等預處理指示符聲明來完成。

2. 隱式柵障

在開始之前,先介紹一下并行區域中的隱式柵障。

柵障(Barrier)是OpenMP用于線程同步的一種方法。線程遇到柵障時必須等待,直到并行的所有線程都到達同一點。

注意:

在任務分配for循環和任務分配section結構中隱含了柵障,在parallel, for, sections, single結構的最后,也會有一個隱式的柵障。

隱式的柵障。

隱式的柵障會使線程等到所有的線程繼續完成當前的循環、結構化塊或并行區,再繼續執行后續工作??梢允褂胣owait去掉這個隱式的柵障。

3. nowait事件同步

nowait用來取消柵障,其用法如下:

#pragma omp for nowait? //不能使用#pragma omp parallel for nowait

#pragma omp single nowait

示例:

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

#include?

#include?

int?main()

{

#pragma?omp?parallel

{

#pragma?omp?for?nowait

for(int?i?=?0;?i?

{

std::cout?<

}

#pragma?omp?for

for(int?j?=?0;?j?

{

std::cout?<

}

}

return?0;

}

#include

#include

int main()

{

#pragma omp parallel

{

#pragma omp for nowait

for(int i = 0; i < 1000; ++i)

{

std::cout << i << "+" << std::endl;

}

#pragma omp for

for(int j = 0; j < 10; ++j)

{

std::cout << j << "-" << std::endl;

}

}

return 0;

}

運行程序,可以看到第一個for循環的兩個線程中的一個執行完之后,繼續向下執行,因此同時打印了第一個循環的+和第二個循環的-。

如果去掉第一個for循環的nowait生命,則第一個for循環的兩個線程都執行完之后,才開始同時執行第二個for循環。也就是說,通過#pragma omp for聲明的for循環結束時有一個默認的隱式柵障。

4. 顯示同步柵障 #pragma omp barrier

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

#include?

#include?

int?main()

{

#pragma?omp?parallel

{

for(int?i?=?0;?i?

{

std::cout?<

}

#pragma?om?barrier

for(int?j?=?0;?j?

{

std::cout?<

}

}

return?0;

}

#include

#include

int main()

{

#pragma omp parallel

{

for(int i = 0; i < 100; ++i)

{

std::cout << i << "+" << std::endl;

}

#pragma om barrier

for(int j = 0; j < 10; ++j)

{

std::cout << j << "-" << std::endl;

}

}

return 0;

}

運行程序,可以看出兩個線程執行了第一個for循環,當兩個線程同時執行完第一個for循環之后,在barrier處進行了同步,然后執行后邊的for循環。

5. master事件同步

通過#pragma om master來聲明對應的并行程序塊只有主線程完成。

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

#include?

#include?

int?main()

{

#pragma?omp?parallel

{

#pragma?omp?master

{

for(int?j?=?0;?j?

{

std::cout?<

}

}

std::cout?<

}

return?0;

}

#include

#include

int main()

{

#pragma omp parallel

{

#pragma omp master

{

for(int j = 0; j < 10; ++j)

{

std::cout << j << "-" << std::endl;

}

}

std::cout << "This will printed twice." << std::endl;

}

return 0;

}

運行程序,可以看到,進入parallel聲明的并行區域之后,創建了兩個線程。主線程執行了for循環,而另一個線程沒有執行for循環,而直接進入了for循環之后的打印語句,然后執行for循環的線程隨后還會再執行一次后邊的打印語句。

6. sections用來指定不同的線程執行不同的部分

下面通過一個實例來說明其使用方法:

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

#include?

#include?

int?main()

{

//聲明該并行區域分為若干個section,section之間的運行順序為并行

//的關系

#pragma?omp?parallel?sections

for(int?i?=?0;?i?

{

std::cout?<

}

#pragma?omp?section???//第一個section,由某個線程單獨完成

for(int?j?=?0;?j?

{

std::cout?<

}

return?0;

}

#include

#include

int main()

{

//聲明該并行區域分為若干個section,section之間的運行順序為并行

//的關系

#pragma omp parallel sections

for(int i = 0; i < 5; ++i)

{

std::cout << i << "+" << std::endl;

}

#pragma omp section //第一個section,由某個線程單獨完成

for(int j = 0; j < 5; ++j)

{

std::cout << j << "-" << std::endl;

}

return 0;

}

可以看到,并行區域中有兩個線程,所以兩個section同時執行。

總結

以上是生活随笔為你收集整理的openmp 互斥锁 mysql_OpenMP(四)线程同步之互斥锁函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。