1. 程式人生 > >一種簡單的跨平臺互斥鎖

一種簡單的跨平臺互斥鎖

   互斥鎖,用來保證任一時刻只有單個執行緒或程序擁有對共享資源的互斥訪問權,在這裡將posix thread中的互斥體、win32中的互斥體和臨界區,統稱為互斥鎖,其特點如下:
   ● 範圍執行緒鎖程序鎖,前者僅用於同一程序內多執行緒間,而後者用於程序間,顯然,它也能用於同一程序內多執行緒間,但效率較低。posix的互斥體既可以是執行緒鎖,也可以是程序鎖,這由它的一個屬性決定:pthread_process_shared或pthread_process_private。win32中的臨界區是一種執行緒鎖,而互斥體既可以是執行緒鎖,也可以是程序鎖,這由它的一個名稱決定:createmutex中的第3個引數。

   ● 型別:posix中的互斥體,包括普通鎖遞迴鎖檢測鎖適應鎖四種;而win32中的臨界區在同一執行緒內可多次加鎖和解鎖,相當於遞迴鎖,而互斥體則相當於普通鎖。
   ● 操作:包括建立鎖、加鎖、解鎖、檢測鎖和銷燬鎖5種操作,其中加鎖操作又可分為永久等待超時等待2種。對於win32中的臨界區,不存在超時等待的加鎖。

介面   所有鎖操作,成功返回0,失敗posix返回非0的錯誤碼,win32返回-1,呼叫getlasterror可獲取錯誤碼。對於超時加鎖,第2個引數超時不是時間差,而是絕對到期時間。對於win32中的互斥體,廢棄返回1,超時返回2。  1#ifdef _POSIX_THREAD
 2#include <pthread.h> 3#include <sys/time.h> 4
 5typedef pthread_mutex_t mutex_t;
 6typedef pthread_mutexattr_t mutexattr_t;
 7typedef void SECURITY_ATTRIBUTES;
 8
 9#elif defined(_WIN32_THREAD)10#ifndef _WIN32_WINNT
11# define _WIN32_WINNT 0x050112#endif13#include <winsock2.h>14
15typedef struct
16{
17    int type_;
18    union
19    {
20        HANDLE proc_lock_;
21        CRITICAL_SECTION thr_lock_;
22    }
;
23}
mutex_t;
24typedef void mutexattr_t;
25
26#else27#error Currently only support win32 and posix thread models28#endif29
30#define MUTEX_THREAD_SHARED  131#define MUTEX_PROCESS_SHARED 232
33int mutex_init(mutex_t* m,int scope,int type,constchar* name,
34               mutexattr_t* attr,SECURITY_ATTRIBUTES* sa);
35
36int mutex_lock(mutex_t* m);
37
38int mutex_timedlock(mutex_t* m,conststruct timeval* val);
39
40int mutex_trylock(mutex_t* m);
41
42int mutex_unlock(mutex_t* m);
43
44int mutex_destroy(mutex_t* m);
實現    1int mutex_init(mutex_t* m,int scope,int type,constchar* name,mutexattr_t* attr,SECURITY_ATTRIBUTES* sa)
  2{
  3#ifdef _POSIX_THREAD
  4    int ret, init =0;
  5    pthread_mutexattr_t tmp;
  6    if(0==attr) attr =&tmp;
  7    if(attr==&tmp)
  8    {
  9        ret = pthread_mutexattr_init(attr);
 10        if (0==ret) init =1;
 11    }
 12    if(0==ret &&0!= scope)
 13    {
 14#ifdef  _POSIX_THREAD_PROCESS_SHARED
 15        ret = pthread_mutexattr_setpshared(attr,lock_scope);
 16#endif 17    }
 18    if(0==ret &&0!= type)
 19    {
 20#ifdef __USE_UNIX98
 21        ret = pthread_mutexattr_settype(attr,lock_type);
 22#endif 23    }
 24    if (0==ret)
 25        ret = pthread_mutex_init(m,attr);
 26    if (1==init && attr==&tmp)
 27        pthread_mutexattr_destroy(attr);
 28    return ret;
 29#else 30    m->type_ = scope;
 31    switch (m->type_)
 32    {
 33    case MUTEX_THREAD_SHARED:
 34        __try
 35        {
 36            InitializeCriticalSection(&m->thr_lock_);
 37        }
 38        __except(EXCEPTION_EXECUTE_HANDLER)
 39        {
 40            return-1;
 41        }
 42        return0;
 43
 44    case MUTEX_PROCESS_SHARED:
 45        m->proc_lock_ = CreateMutexA(sa,FALSE,name);
 46        if (0==m->proc_lock_&&ERROR_ACCESS_DENIED==GetLastError())
 47            m->proc_lock_ = OpenMutexA(MUTEX_ALL_ACCESS,FALSE,name);
 48        if (0==m->proc_lock_)
 49            return-1;        
 50        return0;
 51
 52    defaultreturn-1;
 53    }
 54#endif 55}
 56
 57int mutex_lock(mutex_t* m)
 58{
 59#ifdef _POSIX_THREAD
 60    return pthread_mutex_lock(m);
 61#else 62    switch(m->type_)
 63    {
 64    case MUTEX_THREAD_SHARED:
 65        EnterCriticalSection(&m->thr_lock_);
 66        return0;
 67    
 68    case MUTEX_PROCESS_SHARED:
 69        switch (WaitForSingleObject (m->proc_lock_, INFINITE))
 70        {
 71        case WAIT_OBJECT_0:  return0;
 72        case WAIT_ABANDONED: return1;
 73        defaultreturn-1;
 74        }
 75        break;
 76
 77    defaultreturn-1
 78    }
 79#endif 80}
 81
 82int mutex_timedlock(mutex_t* m,conststruct timeval* val)
 83{
 84    //val should be an absolute time. 85#ifdef _POSIX_THREAD
 86    struct timespec ts ={.tv_sec = val->tv_sec,.tv_nsec=val->tv_usec*1000};
 87    return pthread_mutex_timedlock(m,&ts);
 88#else 89    switch(m->type_)
 90    {
 91    // not support CriticalSection,so simply return -1. 92case MUTEX_THREAD_SHARED:
 93        return-1
 94
 95    case MUTEX_PROCESS_SHARED:
 96

相關推薦

簡單跨平臺互斥

   互斥鎖,用來保證任一時刻只有單個執行緒或程序擁有對共享資源的互斥訪問權,在這裡將posix thread中的互斥體、win32中的互斥體和臨界區,統稱為互斥鎖,其特點如下:   ● 範圍:執行緒鎖和程序鎖,前者僅用於同一程序內多執行緒間,而後者用於程序間,顯然,它也能用於同一程序內多執行緒間

簡單跨平臺使用者態自旋

   自旋鎖作為一種併發同步的手段,特別適用於競爭少和鎖時間短的情況,在驅動及核心程式碼中經常被用到,本文講述一種適合使用者態程式的自旋鎖,支援Windows和Linux(GCC>=4.1.2)平臺,並提供了C語言的介面和實現。 介面   spin_trylock如果獲取成功返回1,否

簡單跨平臺訊號量

   訊號量是一種用於併發環境同步手段的原語,分為無名訊號量和有名訊號量兩種,前者只能用於執行緒間同步,而後者還可用於程序間同步。它包括建立、等待、掛出、取值和銷燬5種基本操作。與互斥鎖不同的是:    ● 訊號量擁有一個計數值,表示可用的資源數量,僅當該值為0或1時,則相當於互斥鎖。    

簡單跨平臺套接字管道

{ 49    SOCKET client = INVALID_SOCKET,server=INVALID_SOCKET; 50    struct addrinfo addr,*res = NULL; 51    constchar* address; 52    int opt =1; 53 54    

簡單的加解密算法

coder 額外 lai hack crypt decrypt pro simple 無需   此算法源碼最初由 Borland 的 Delphi 語言編寫,似乎 Allen Bauer 是原作者,源碼如下。 const cMulKey = 52845; cA

SpringBank 開發日誌 簡單的攔截器設計實現

exp bst 一個 pin factory span 之前 system request 當交易由Action進入Service之前,需要根據不同的Service實際負責業務的不同,真正執行Service的業務邏輯之前,做一些檢查工作。這樣的攔截器應該是基於配置的,與Se

簡單的生產環境部署Node.js程序方法

set process 一次 ann 來安 環境配置 load 修改 evel 最近在部署Node.js程序時,寫了段簡單的腳本,發覺還挺簡單的,忍不住想與大家分享。 配置文件 首先,本地測試環境和生產環境的數據庫連接這些配置信息是不一樣的,需要將其分開為兩個文件存儲

簡單的對象賦值方法,定義實例後以{}賦值,比傳統方法更簡潔

method ott static set num arr nbsp st2 () public class Rectangle { public Point TopLeft { get; set; } public Point Botto

簡單的圖像修復方法

col nes gb2 tle .com splay 產生 end left 該方法可以用於美顏中的祛斑,通過快速叠代的方式去除斑點。 假設輸入圖像為: 計算方向權重: 對於其他方向,操作類似We。 最終的輸出為: 對要修復的區域,反復進行同樣的操作即可。 簡單

基於redis的分布式

thread 語法 客戶端 read not end 過程 == 直接 前言:本文介紹了一種基於redis的分布式鎖,利用jedis實現應用(本文應用於多客戶端+一個redis的架構,並未考慮在redis為主從架構時的情況) 文章理論來源部分引自:https://i.cnb

php生成excel的另簡單方法

.com com span 來看 nbsp pan blog table content 之前我用table的方式寫過excel,還用php-excel這個類庫寫過excel。今天,我再向大家推薦一個超級簡單的寫excel的方法。 代碼: $xstr = "問題id\t問

java安全性的簡單思路

授權 安全 時間格式 判斷 第三方接口 對比 當前時間 服務 格式 關於接口安全性的考慮。這客戶端在調用接口時,將acId授權碼以加密的方式(可逆加密方式)傳遞過來, 服務端這邊接收後進行解密,然後在服務器端這邊的授權名單中進行匹配,判斷該授權碼是否被授權,從而判斷第三方調

數獨問題的簡單演算法程式碼實現

五一期間無聊時想起去年考研複試有一道上機題目當時沒作出來,於是一時興起想重新拾起看看是當時太緊張,還是自己能力不足。然後發現這道題目還真稍微有些難度,相當於一道數獨問題(sudoku)的簡化版。自己想來想去也只能想到兩種演算法,一種是拿剩餘元素做全排列測試,一種是回溯法測試。最後只實現了一個全排

關於ASP.NET MVC 5 的簡單的身份驗證方式:FormsAuthentication.Authenticate

在ASP.NET MVC 5中,身份驗證分別有三種方式。分別為使用FormsAuthentication、MemberShip和Identity進行驗證。   (PS:本系列的邏輯程式碼請勿直接用於生產,請自己多加一層抽象後再投入使用)   為了展示這三種方式,我們先新建一個MVC

Python單例的簡單寫法

this args self. name 創建方式 方法 沒有 easily 獲取 最原始的想法就是每個類都重寫new方法。 class Dog: dog = None def __new__(cls, *args, **kwargs):

判斷中文文字編碼格式是gbk還是utf-8的簡單方式

import java.io.*; public class charsetTest { public static String charsetType(String fileName) throws IOException { BufferedReader reader =

LCG(linear congruential generator): 簡單的隨機數生成演算法

目錄 LCG演算法 python 實現 LCG演算法 LCG(linear congruential generator)線性同餘演算法,是一個古老的產生隨機數的演算法。由以下引數組成: 引數 m a c X

LCG(linear congruential generator): 簡單的隨機數生成算法

ble 優點 line 寫入 head 速度 body generator 上一個 目錄 LCG算法 python 實現 LCG算法 LCG(linear congruential generator)線性同余算法,是一個古老的產生隨機數的算法。由以下參數組成:

什麼是REST——適合初學者的簡單解釋,第一部分:介紹

  原文地址:https://medium.com/extend/what-is-rest-a-simple-explanation-for-beginners-part-1-introduction-b4a072f8740f     這篇文章是解釋REST基本概念的兩篇文章中的第一篇。      閱讀

pytroch用自定義的tensor初始化nn.sequential中linear或者conv層的簡單方法。

話不多說,上程式碼,上面寫的很清楚。 import torch.nn as nn import torch net= nn.Sequential( nn.Linear(1024, 512), nn.ReLU(inplace=True), nn.Linear(512,