Linux下实现线程同步互斥的方法 (linux 线程同步互斥)

在多线程编程中,线程之间的同步和互斥是非常重要的话题,特别是在多个线程需要同时访问共享资源的情况下,同步和互斥更是不可或缺的。在Linux系统下,有多种方法可以实现线程的同步和互斥,下面将介绍几种较为常见的方法。

一、互斥锁

互斥锁也称为互斥量,是一种用于保护共享资源的锁。它可以通过对于需要访问共享资源的线程进行加锁和解锁的操作来保证共享资源的互斥性。在Linux系统下,可以使用pthread_mutex_t来定义互斥锁。下面是一个简单的互斥锁的使用示例:

“`c

#include

#include

pthread_mutex_t mutex;

int shared_data = 0;

void *worker(void *arg) {

pthread_mutex_lock(&mutex);

shared_data += 1;

printf(“Update shared data to %d\n”, shared_data);

pthread_mutex_unlock(&mutex);

return NULL;

}

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

pthread_t t1, t2;

pthread_mutex_init(&mutex, NULL);

pthread_create(&t1, NULL, worker, NULL);

pthread_create(&t2, NULL, worker, NULL);

pthread_join(t1, NULL);

pthread_join(t2, NULL);

pthread_mutex_destroy(&mutex);

return 0;

}

“`

在上面的示例中,定义了一个全局变量shared_data和一个互斥锁mutex。在worker函数中,首先调用`pthread_mutex_lock`来申请互斥锁,然后对共享资源shared_data进行更新,最后调用`pthread_mutex_unlock`来释放互斥锁。在mn函数中,创建了两个线程分别执行worker函数,并且在最后调用了`pthread_mutex_destroy`来销毁互斥锁。

二、条件变量

条件变量是一种能够支持在共享资源满足某种特定条件时,让线程在等待状态下暂停自己运行的机制。在Linux系统下,可以使用`pthread_cond_t`来定义条件变量,以及相关的`pthread_cond_wt`和`pthread_cond_signal`等函数来实现条件变量的使用。下面是一个简单示例:

“`c

#include

#include

#include

pthread_cond_t cond;

pthread_mutex_t mutex;

int shared_data = 0;

void *worker_producer(void *arg) {

while (1) {

pthread_mutex_lock(&mutex);

shared_data += 1;

printf(“Produce %d\n”, shared_data);

pthread_cond_signal(&cond);

pthread_mutex_unlock(&mutex);

sleep(1);

}

return NULL;

}

void *worker_consumer(void *arg) {

while (1) {

pthread_mutex_lock(&mutex);

while (shared_data == 0) {

pthread_cond_wt(&cond, &mutex);

}

shared_data -= 1;

printf(“Consume %d\n”, shared_data);

pthread_mutex_unlock(&mutex);

sleep(1);

}

return NULL;

}

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

pthread_t t_producer, t_consumer;

pthread_mutex_init(&mutex, NULL);

pthread_cond_init(&cond, NULL);

pthread_create(&t_producer, NULL, worker_producer, NULL);

pthread_create(&t_consumer, NULL, worker_consumer, NULL);

pthread_join(t_producer, NULL);

pthread_join(t_consumer, NULL);

pthread_cond_destroy(&cond);

pthread_mutex_destroy(&mutex);

return 0;

}

“`

在上面的示例中,定义了一个全局变量shared_data和一个互斥锁mutex,并且定义了一个条件变量cond。在worker_producer函数中,不断地对共享资源shared_data进行更新,并且通过`pthread_cond_signal`来通知worker_consumer线程去执行,并且最后调用`pthread_mutex_unlock`来释放互斥锁。在worker_consumer函数中,首先调用`pthread_mutex_lock`来申请互斥锁,然后通过while循环来判断共享资源是否满足条件,如果满足条件,则执行相关的操作,如果不满足条件,则调用`pthread_cond_wt`来暂停自己的运行,并且等待worker_producer线程来唤醒它。在mn函数中创建了两个线程分别执行worker_producer函数和worker_consumer函数,并且在结束时进行一些资源的销毁和清理工作。

相关问题拓展阅读:

  • Linux信号量

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 线程同步互斥的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

香港服务器首选树叶云,2H2G首月10元开通。
树叶云(shuyeidc.com)提供简单好用,价格厚道的香港/美国云服务器和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/158935.html<

(0)
管理的头像管理
上一篇2025-03-17 01:53
下一篇 2025-03-17 01:54

相关推荐

  • 服务器域名解析失败怎么排查,是什么原因造成的?

    服务器域名解析失败的根本原因在于DNS系统无法将域名正确转换为IP地址,排查应遵循从客户端到服务端的顺序:先检查本地网络和DNS缓存,再验证域名解析记录和权威服务器状态,第一步:检查本地网络与DNS设置测试网络连通性先确认你的设备是否正常联网,打开命令提示符或终端,输入ping 8.8.8.8,如果返回回复数据……

    2026-07-27
    0
  • 站群服务器怎么设置不同环境配置,有哪些注意事项?

    站群服务器设置不同的环境配置,核心在于通过虚拟化或容器化技术实现站点隔离,再结合Web服务器配置为每个站点分配独立的PHP版本、数据库及运行参数,从而满足多样化需求,为什么站群服务器需要环境隔离?不同CMS依赖的PHP版本差异明显,例如WordPress推荐PHP 7.4以上,而Drupal 7仍基于PHP 5……

    2026-07-27
    0
  • 站群服务器如何批量管理更高效,有哪些管理技巧?

    站群服务器批量管理想提效,自动化是唯一出路,通过统一配置管理工具与面板系统,结合服务商提供的底层基础设施支持,能将运维效率提升数倍,批量管理的核心痛点与解决思路多台站群服务器分散管理,最常见的问题就是重复劳动,每次软件更新、配置修改、安全加固,都需要逐台登录操作,不仅耗时,还容易漏掉某台机器,更头疼的是,一旦某……

    2026-07-27
    0
  • 服务器磁盘IO过高如何优化?,磁盘IO过高的原因有哪些?

    服务器磁盘IO过高,核心优化路径是“先定位、再分流、后升级”,你需要通过系统工具精确判断究竟是应用程序、日志策略还是硬件瓶颈导致,然后针对性地从代码、缓存、存储架构和硬件选型四个层面下手,其中选择持有持牌自营机房和增值电信业务经营许可证的服务商,能从根本上保障底层IO稳定性,定位IO瓶颈:动手优化的第一步盲目优……

    2026-07-27
    0
  • 跨境网站访问延迟高怎么解决,网站访问慢的原因是什么?

    跨境网站访问延迟高的核心解决思路在于多维度优化网络路径,包括使用全球CDN加速、选择靠近目标区域的优质IDC机房、调整传输协议以及精简应用层资源,其中服务商的基础设施质量直接决定优化上限,为什么跨境访问延迟高?三大核心因素物理距离与光速限制数据包在海底光缆中的传输速度受限于介质,从中国到美国西海岸的物理往返时间……

    2026-07-27
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注