进程间通过线程锁实现互斥

进程间通过线程锁实现互斥

前言

我们知道进程间实现互斥一般使用信号量等,而线程实现互斥一般使用的是线程锁。那么可以不可以使用线程锁,应用到进程之间实现互斥呢?

本着探索的精神,试着写出了代码,通过实际代码运行结果的确是行得通的。

思想:
  1. 先创建互斥锁变量、互斥锁属性变量,然后把锁属性设置为进程间共享方式
  2. 创建一块共享内存,然后把锁变量传入共享内存。同时定义一个变量num,初始化为2千万
  3. fork创建一个子进程,父子进程同时对num减1操作,直至为0。然后分别记录每个进程执行了多少次
  4. 如果父子进程操作次数相加正好等于2千万,说明父子进程对num这个临界资源是互斥的访问
代码:(vim编辑器、gcc编译器)
/* 此头文件为自己定义的,里面包含所有代码依赖的头文件,
方便测试代码,不用每次都加头文件,工作中不建议这样写,
代码中只包含代码必要依赖的头文件。此代码如需在你自己电脑运行,
需自行手动添加头文件 */ 
#include <head.h>

int main(int argc, char** argv)
{
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);

    //将线程锁设置为进程间共享
    pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&mutex, &attr);

    int shmid = shmget(1000, 4096, IPC_CREAT|0600);
    ERROR_CHECK(shmid, -1, "shmget");

    int *p = (int*)shmat(shmid, NULL, 0);

    //将线程锁放到共享内存中
    memcpy(p, &mutex, sizeof(mutex));

    int num = 20000000;
    int len = sizeof(mutex);
    memcpy(p+len, &num, sizeof(int));

    if(fork()){
        int sum = 0;
        int ret = 0;
        while(1){
            ret = pthread_mutex_lock((pthread_mutex_t*)p);
            
            //自己对strerror的封装的一个检查宏
            THREAD_ERROR_CHECK(ret, "lock");
            if(*(p+len)){
                *(p+len) -= 1;
                sum++;
            }
            else{
                ret = pthread_mutex_unlock((pthread_mutex_t*)p);
                THREAD_ERROR_CHECK(ret, "unlock");
                break;
            }
            ret = pthread_mutex_unlock((pthread_mutex_t*)p);
            THREAD_ERROR_CHECK(ret, "unlock");
        }
        wait(NULL);
        printf("mian sum = %d\n", sum);
    }
    else{
        int ret = 0;
        int sum = 0;
        while(1){
            ret = pthread_mutex_lock((pthread_mutex_t*)p);
            THREAD_ERROR_CHECK(ret, "lock");
            if(*(p+len)){
                *(p+len) -= 1;
                sum++;
            }
            else{
            ret = pthread_mutex_unlock((pthread_mutex_t*)p);
            THREAD_ERROR_CHECK(ret, "unlock");
                break;
            }
            ret = pthread_mutex_unlock((pthread_mutex_t*)p);
            THREAD_ERROR_CHECK(ret, "unlock");
        }
        printf("child sum = %d\n", sum);
    }
    shmdt(p);
    return 0;
}

运行结果:(运行了10次,每次相加都正好为两千万,本次实验有效)

在这里插入图片描述

原创博客,欢迎转载,转载请注明出处。

如有错误欢迎批评指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值