首页 > 其他分享 >通过互斥锁+条件量的方式实现同步与互斥

通过互斥锁+条件量的方式实现同步与互斥

时间:2024-05-31 18:55:40浏览次数:14  
标签:同步 thread int 条件 NULL 互斥 pthread include buff

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h> // for O_CREAT and O_EXCL
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>

#define SHM_SIZE 4

// 定义条件量,互斥锁和共享内存
int shm_id;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t flag = PTHREAD_COND_INITIALIZER;

// 线程A
void *increment_thread(void *arg)
{
    while (1)
    {
        pthread_mutex_lock(&mut); // 上锁
        int *buff = (int *)shmat(shm_id, NULL, 0);
        *buff = (*buff) + 1;
        int temp = *buff;
        printf("主线程写入共享内存的值为:%d\n", buff[0]);
        shmdt(buff);
        if (temp % 3 == 0)//判断是否满足条件唤醒线程B
        {
            pthread_cond_broadcast(&flag);
        }
        pthread_mutex_unlock(&mut); // 解锁
        sleep(1);
    }
}

// 线程B
void *decrement_thread(void *arg)
{
    while (1)
    {
        pthread_mutex_lock(&mut);       // 上锁
        pthread_cond_wait(&flag, &mut); // 不满足条件挂起
        int *buff = (int *)shmat(shm_id, NULL, 0);
        printf("\n\n满足条件子线程B输出当前i值为:%d\n\n", buff[0]);
        shmdt(buff);
        pthread_mutex_unlock(&mut); // 解锁
    }
}

int main(int argc, char *argv[])
{
    pthread_t inc_thread, dec_thread;

    // 创建共享内存
    shm_id = shmget(ftok(".", 50), SHM_SIZE, IPC_CREAT | IPC_EXCL | 0644);
    // 函数调用失败,原因是共享内存段已经存在
    if (shm_id == -1)
    {
        if (errno == EEXIST) // 此时可以再次调用函数打开共享内容
        {
            shm_id = shmget(ftok(".", 50), SHM_SIZE, 0644);
        }
        else
        {
            fprintf(stderr, "shmget error,error:%d,%s\n", errno, strerror(errno));
            exit(1);
        }
    }

    // 映射共享内存段到进程空间中并赋予初值1
    int *buff = (int *)shmat(shm_id, NULL, 0);
    if (errno == EEXIST) // 此时可以再次调用函数打开共享内容
    {
        shm_id = shmget(ftok(".", 50), SHM_SIZE, 0644);
    }
    else
    {
        fprintf(stderr, "shmget error,error:%d,%s\n", errno, strerror(errno));
        exit(1);
    }
    *buff = 1;
    shmdt(buff);

    // 创建线程
    if (pthread_create(&inc_thread, NULL, increment_thread, NULL) != 0)
    {
        perror("pthread_create");
        sem_unlink("/sem1");
        sem_unlink("/sem2");
        exit(EXIT_FAILURE);
    }

    if (pthread_create(&dec_thread, NULL, decrement_thread, NULL) != 0)
    {
        perror("pthread_create");
        sem_unlink("/sem1");
        sem_unlink("/sem2");
        exit(EXIT_FAILURE);
    }

    // 等待线程完成
    if (pthread_join(inc_thread, NULL) != 0)
    {
        perror("pthread_join");
        sem_unlink("/sem1");
        sem_unlink("/sem2");
        exit(EXIT_FAILURE);
    }

    if (pthread_join(dec_thread, NULL) != 0)
    {
        perror("pthread_join");
        sem_unlink("/sem1");
        sem_unlink("/sem2");
        exit(EXIT_FAILURE);
    }

    // 关闭共享内存
    shmctl(shm_id, IPC_RMID, NULL);

    printf("All threads completed successfully.\n");
    return 0;
}

标签:同步,thread,int,条件,NULL,互斥,pthread,include,buff
From: https://www.cnblogs.com/eon4051/p/18225135

相关文章

  • 向GitHub远程仓库同步文件使用经验【2】
    新手流畅一顿操作由于没搞懂CSDN的更新文档策略,只能把新写的内容作为新文章发布了。前一篇文章在这将本地仓库与远程仓库同步当本地仓库没修改,但远程仓库修改了,这时可以吧远程仓库同步到本地仓库===方法一===gitfetch //将本地仓库中的远程分支更新成了远程仓库相应......
  • PMSM永磁同步电机滑膜控制SVPWM矢量控制(Simulink仿真实现)
      ......
  • 互斥锁练习题
    练习:设计一个程序,程序中有3个线程,主线程A创建一个文本,每隔5s获取一次系统时间并写入到该文本中,另外两个线程B和C分别从文本中读取当前的时间和日期,子线程B输出系统时间"hh:mm:ss",子线程c输出系统日期"2024年05月31日”,要求使用读写锁实现互斥。提示:主线程A获取写操作的锁,另外......
  • Rsync数据同步
    目标端配置:一、安装yum-yinstallrsync二、配置文件vi/etc/rsyncd.conf用户iduid=rsync组idgid=rsync程序安全设置usechroot=no客户端连接数maxconnections=200进程号文件位置pidfile=/var/run/rsyncd.pid进程锁文件位置lockfile=/var/run/rsy......
  • flutter - [03] 运算符&条件表达式
    题记部分 一、算术运算符运算符说明示例(a=13,b=5)+加print(a+b);-减print(a-b);*乘print(a*b);/除print(a/b);~/取整print(a~/b);%取余print(a%b);   二、关系运算符  三、逻辑运算符  四、赋值运算符 五、条件......
  • SAP ABAP 对工作区列遍历或按条件访问
    需要对字段数量多的工作区或动态工作区进行数据处理时,列遍历可使代码更加的简洁高效。(๑¯ω¯๑)重新发一遍,丢合集里示例代码:点击查看代码TYPES:BEGINOFtyp_kna1,kunnrTYPEkna1-kunnr,"客户编号name1TYPEkna1-name1,"送达方名......
  • 34.MySQL数据库【四】过滤条件
    过滤条件【一】语法select*/字段名from*/表名where*/字段名=字段值;--执行顺序from起手知道是那张表where根据过滤条件在表中过滤数据select再过滤出自己想要的数据【二】准备的数据#创建表createtablefilt_eg( idintnotnulluniqueauto_increment,......
  • 33.MySQL数据库【三】约束条件
    约束条件限制表中的数据,保证数据的准确性和可靠性而存在的限制规则【一】非空约束(notnull)限制指定字段不能为空#建表createtableeg( namevarchar(32)notnull, hobbyvarchar(32));#name字段不能为空【二】唯一性约束(unique)限制字段具有唯一性,不能重复,但能为......
  • Shell脚本---条件判断
    1.条件判断语法结构思考:何为真(True)?何为(False)?格式1:test条件表达式格式2:[条件表达式]格式3:[[条件表达式]]支持正则=~特别说明:1)[中括号两边都有空格]2)[[中括号两边都有空格]]3)更多判断,mantest去查看,很多的参数都用来进行条件判断2.条件判断相关参......
  • c# NTP 时间同步
    using System;using System.Collections.Generic;using System.Text;using System.Net;using System.Net.Sockets;namespace SmartConstructionSite.Common.Helper{    public class NTPHelper    {        public const string WINDOWS_SE......