了解Linux同步互斥锁,实现线程安全的编程 (linux 同步互斥锁)

随着计算机应用环境的日益复杂,用户对计算机系统的要求也变得越来越高,这就要求计算机系统必须能够并发地处理各种任务。而线程便是实现并行处理的基本单元之一。不过,由于线程是并发的,多线程程序的编写过程中,就需要考虑线程之间数据的同步问题,否则就会导致数据混乱、死锁等问题。为解决这些问题,就需要使用同步互斥锁。

1. 了解同步互斥锁

同步互斥锁是一种常用的线程同步机制,它可以确保在任意时刻只有一个线程执行关键代码段,保证代码的互斥性。在Linux系统中,同步互斥锁可以由pthread_mutex_t类型的互斥锁对象实现。当一个线程需要使用共享数据时,它必须先锁定该互斥锁,执行完操作之后再释放该互斥锁,以允许其他线程继续使用该共享数据。

2. 实现线程安全编程

线程安全的编程是指在多线程环境下保证程序正常运行的能力。使用同步互斥锁可以实现线程安全编程。在进行线程编程时,需要注意以下几点。

(1)对于需要访问共享资源的变量,需要使用互斥锁进行保护。

(2)对于一组共享资源,可以使用一把互斥锁进行保护,避免多个线程同时访问。

(3)在设计线程程序时,需要注意“死锁”问题,即两个或多个线程互相等待对方释放锁的情况。

(4)使用条件变量可以实现线程之间的通信,避免不必要的上锁。

3. 代码示例

下面是一个简单的示例代码,演示了使用同步互斥锁实现线程安全的方法。

“`

#include

#include

#include

typedef struct __counter_t { //定义计数器结构体

int value;

pthread_mutex_t lock;

} counter_t;

void init(counter_t *c) { //初始化计数器

c->value = 0;

pthread_mutex_init(&c->lock, NULL);

}

void increment(counter_t *c) { //自增操作

pthread_mutex_lock(&c->lock); //上锁

c->value++;

pthread_mutex_unlock(&c->lock); //解锁

}

void decrement(counter_t *c) { //自减操作

pthread_mutex_lock(&c->lock); //上锁

c->value–;

pthread_mutex_unlock(&c->lock); //解锁

}

int get(counter_t *c) { //获取计数器的值

pthread_mutex_lock(&c->lock); //上锁

int val = c->value;

pthread_mutex_unlock(&c->lock); //解锁

return val;

}

int mn(int argc, char *argv[]) {

counter_t c;

init(&c);

int i;

for (i = 0; i

increment(&c);

}

for (i = 0; i

decrement(&c);

}

printf(“FINAL VALUE: %d\n”, get(&c));

return 0;

}

“`

在这段代码中,我们使用了一个计数器结构体来管理计数器的值。在自增、自减、获取计数器值的操作中,我们都使用了同步互斥锁进行保护,以确保计数器的操作是线程安全的。此外,我们在程序开头还创建了一个互斥锁对象并进行初始化。

4.

相关问题拓展阅读:

linux|进程间通信如何加锁

进程间通信有一种方式,大家有没有想过,这种通信方式中如何解决数据竞争问题?我们可能自然而然的就会想到用锁。但我们平时使用的锁都是用于解决线程间数据竞争问题,貌似没有看到过它用在进程中,那怎么办?

关于进程间的通信方式估计大多数人都知道,这也是常见的面试八股文之一。

个人认为这种面试题没什么意义,无非就是答几个关键词而已,更深入的可能面试官和面试者都不太了解岩凯销。

关于进程间通信方式我之前在【这篇文章】中有过介绍,感兴趣的可以移步去看哈。

进程间通信有一种方式,大家有没有想过,这种通信方式中如何解决数据竞争问题?

我们可能自然而然的就会想到用锁。但我们平时使用的锁都是用于解决线程间数据粗游竞争问题,貌似没有看到过它用在进程中,那怎么办?

我找到了两种方法,信号量和互斥锁。

直接给大家贴代码吧,首先是信号量方式:

代码中的MEOW_DEFER,它内部的函数会在生命周期结束后触发。它的核心函数其实就是下面这四个:

具体含义大家应该看孙禅名字就知道,这里的重点就是sem_init中的pshared参数,该参数为1表示可在进程间共享,为0表示只在进程内部共享。

第二种方式是使用锁,即pthread_mutex_t,可是pthread_mutex不是用作线程间数据竞争的吗,怎么能用在进程间呢?

可以给它配置一个属性,示例代码如下:

它的默认属性是进程内私有,但是如果给它配置成PTHREAD_PROCESS_SHARED,它就可以用在进程间通信中。

相关视频推荐

360度无死角讲解进程管理,调度器的5种实现

Linux进程间通信-信号量、消息队列和共享内存

学习视频教程-腾讯课堂

需要C/C++ Linux服务器架构师学习资料加qun获取(资料包括

C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg

等),免费分享

完整代码如下:

我想这两种方式应该可以满足我们日常开发过程中的大多数需求。

锁的方式介绍完之后,可能很多朋友自然就会想到原子变量,这块我也搜索了一下。但是也不太确定C++标准中的atomic是否在进程间通信中有作用,不过看样子boost中的atomic是可以用在进程间通信中的。

其实在研究这个问题的过程中,还找到了一些很多解决办法,包括:

Disabling Interrupts

Lock Variables

Strict Alternation

Peterson’s Solution

The TSL Instruction

Sleep and Wakeup

Semaphores

Mutexes

Monitors

Message Passing

Barriers

求教:线程同步和进程同步有什么区别

线程同步:多线程编程中,解决共享资源冲突的问题

进程同步毕亏:多进程编程中,解决共享资源冲突的问题

但是部分同学对线程同步和进程同步研究得不够深入,烂耐比如

互斥锁

和条件变量能不能同时用于线程同步和进程同步,本质上有什么区别。

首先我们知道,linux下每个进程都有自己的独立进程空间,假设A进程和B进程各有一个互斥锁,这个锁放在进程的全局静态区,那么AB进程都是无法感知对方的互斥锁的。

互斥锁和条件变量出自Posix.1线程标准,它们总是可以用来同步一个进程内的各个线程的。如果一个互斥锁或者条件变量存放在多个进程共享的某个内存区中,那么Posix还允许它用在这些进程间的同步。饥数春

看到这里,是不是发现点了什么,线程同步和进程同步的本质区别在于锁放在哪,放在私有的进程空间还是放在多进程共享的空间,并且看锁是否具备进程共享的属性,

进程至少包括一个主线程,还并物穗有工作线程

狭隘的讲:线程通信就是进程范围内主线程与工作线程 或者 工作线程之间的通信

进程通信,是进程A(可以理绝卜解为主线程) 与 进程B(可以理解为主线程)之蚂型间的通信

浅谈linux和windows的线程机制的区别

  转载自fychit创意空间 早前想写写linux线程编程windows线程编程每写知道哪写起自知道东西都写面我谈谈linux线程及线程同步并windows线程进行比较看看间相同点同

  其实始我搞windows编程包括windows编程windows 驱包括u驱ndis驱,pci驱1394驱等等同条龙服务做windows应用程序发面慢慢我linux发产比较深兴趣转搞linux发接我写些博客主要写linux编程windows编程区别吧现想写linuxu驱windowsu驱发区别些都等我linux线程windows线程讲解完我再写篇u驱谈谈windows linux u驱东东言归传始线程

  首先我讲讲要采用线程编程其实并所程序都必须采用线程些候采用线程性能没单线程所我要搞清楚候采用线程采用线程处:

  (1)线程彼间采用相同址空间共享部数据进程相比代价比较节俭进程启新进程必须配给独立址空间需要数据表维护代数雀码段数据段堆栈段等等

  (2)线程进程相比明显优点线程间通信同进程说具独立数据空间要进行数据传递能通通信式进行种式仅费且便于线程间直接共享数据比简单式共享全局变量共享全部变量要注意哦呵呵必须注意同步知道呵呵

  (3)cpu情况同线程运行同cpu完全并行

  反我觉种情况采用线程比较理想比说要做任务2步骤提高工作效率线程技术辟2线程第线程做第步工作第2线程做第2步工作候要注意同步第步做完才能做第2步工作我采用同步技术进行线程间通信

  针种情况我首先讲讲线程间通信windows平台线程间通信采用主要:

  (1)共享全局变量,种容易想呵呵首先讲讲吧比说吧面问题第步要向第2步传扒游递收据我间共享全局变量让两线程间传递数据主要考虑同步面线程数据进行操作候第线程改变数据内容同步保护严重知道种情况读脏数据种情况我容易想同步设置bool flag比说第2线程没用完数据前第线程能写入2线程所需间相同候达效率同步比较麻烦咱几缓冲区进行操作像产者消费者2线程直跑由于间致缓冲区迟早溢种情况要考虑让数据写入让数据覆盖掉数据候要具体问题具体析打住呵呵用bool变量控制同步linux windows

  既讲道再讲讲其同步同 针面问题共享全局变量同步问题除采用bool变量外容易想互斥量呵呵传说加锁windows加锁linux加锁类似采用互斥量进行同步要想进入段代码先必须获互斥量

  linux互斥量函数:

  windows互斥量函数:createmutex 创建互斥量获互斥量waitforsingleobject函数用完释放互斥量ReleaseMutex(hMutex)减0候 内核才释放其象面windows与互斥几函数原型

  HANDLE WINAPI CreateMutex(

  __in LPSECURITY_ATTRIBUTES lpMutexAttributes,

  __in BOOL bInitialOwner,

  __in LPCTSTR lpName

  );

  用创建名或名互斥量象

  第参数 指向结构体SECURITY_ATTRIBUTES 般设null;

  第二参数 指函数应应状态 FALSE前拥者创建互斥

  第三参数 指明否名互斥象 名 用null

  DWORD WINAPI WaitForSingleObject(

  __in HANDLE hHandle,

  __in DWORD dwMilliseconds

  );

  第 创建互斥象句柄第二 表示少间返 设宏INFINITE 则返 直用户自定义返

  于linux操作系统互斥类似函数同罢linux互斥春毕销相关几函数要闪亮登场

  pthread_mutex_init函数:初始化互斥锁;

  pthread_mutex_destroy函数:注销互斥锁;

  pthread_mutex_lock函数:加锁功阻塞等待;

  pthread_mutex_unlock函数:解锁;

  pthread_mutex_trylock函数:测试加锁功立即返错误码EBUSY;

  至于些函数用google搜呵呵讲windows用保护数据线程同步式

  临界区临界区互斥类似间区别临界区速度快能用同步同进程内线程临界区获取释放函数:

  EnterCriticalSection() 进入临界区; LeaveCriticalSection()离临界区 于线程共享内存东东讲

  (2)采用消息机制进行线程通信同步windows面消息机制函数用postmessageLinux消息机制我用较少说谁熟悉告诉我呵呵

  (3)windows另外种线程通信事件信号量同针我始举例2线程同步间传递信息采用事件(Event)或信号量(Semaphore),比第线程完产数据必须告诉第2线程已经数据准备取走第2线程数据取走呵呵采用消息机制第线程准备数据直接postmessage给第2线程按理说采用postmessage线程搞定问题呵呵重点省略讲

  于linux类似条件变量呵呵windowslinux同要特别讲讲才行

  于windows采用事件信号量同步候都使用waitforsingleobject进行等待函数第参数句柄Event句柄或Semaphore句柄第2参数等待延迟终等久单位ms参数INFINITE限等待释放信号量函数ReleaseSemaphore();释放事件函数SetEvent使用些东西都要初始化讲Msdn搜神马都呵呵神马都浮云

  于linux操作系统采用条件变量实现类似功能Linux条件变量般都互斥锁起使用主要函数:

  pthread_mutex_lock ,

  pthread_mutex_unlock,

  pthread_cond_init

  pthread_cond_signal

  pthread_cond_wait

  pthread_cond_timewait

关于linux 同步互斥锁的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 了解Linux同步互斥锁,实现线程安全的编程 (linux 同步互斥锁)