5进程间锁:进程间pthread_mutex,文件锁



1进程间pthread_mutex

A依赖的头文件

#include<pthread.h>

B
函数声明

intpthread_mutexattr_destroy(pthread_mutexattr_t *attr);

intpthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);

intpthread_mutexattr_init(pthread_mutexattr_t *attr);

关于pshared可供选的参数:

线程锁:PTHREAD_PROCESS_PRIVATE

进程锁:PTHREAD_PROCESS_SHARED

默认情况下是线程锁

C
案例说明:


#include <stdio.h>

#include <pthread.h>

#include <unistd.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>

#include <sys/mman.h>

#include <string.h>

#include <sys/wait.h>

struct mt {

int num;

pthread_mutex_t mutex;

pthread_mutexattr_t mutexattr;

};

int main(void) {

int fd,i,err;

struct mt *mm;

pid_t pid;

fd = open("mt_test",O_CREAT|O_RDWR,0777);

/*不需要write,文件里初始值为0*/

ftruncate(fd,sizeof(*mm));

mm = mmap(NULL,sizeof(*mm),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

close(fd);

memset(mm,0,sizeof(*mm));

/*初始化互斥对象属性*/

pthread_mutexattr_init(&mm->mutexattr);

/*

* 设置互斥对象为PTHREAD_PROCESS_SHARED共享,即可以在多个进程的

*线程访问,PTHREAD_PROCESS_PRIVATE为同一进程的线程共享

*/

pthread_mutexattr_setpshared(&mm->mutexattr,PTHREAD_PROCESS_SHARED);

pthread_mutex_init(&mm->mutex,&mm->mutexattr);

pid = fork();

if(pid == 0) {

/*加10次。相当于加10*/

for(i = 0;i < 10;i++) {

//在子进程上对文件进行上锁

pthread_mutex_lock(&mm->mutex);

(mm->num)++;

printf("num++:%d\n",mm->num);

//解锁

pthread_mutex_unlock(&mm->mutex);

sleep(1);

}

} else if(pid > 0) {

/*父进程完成x+2,加10次,相当于加20*/

for (i = 0;i < 10;i++) {

pthread_mutex_lock(&mm->mutex);

mm->num += 2;

printf("num+=2:%d\n",mm->num);

pthread_mutex_unlock(&mm->mutex);

sleep(1);

}

wait(NULL);

}

err = pthread_mutex_destroy(&mm->mutex);

if(err != 0) {

printf("%s\n",strerror(err));

}

/* 父子均需要释放 */

munmap(mm,sizeof(*mm));

unlink("mt_test");

return 0;

}

运行结果:

总结:

a进程间通信,可以通过内存映射的方式对文件进行操作。

b在上锁的情况下,数字相加后最后得到的是30,加锁后没有出现冲突。

2
文件锁

使用fcntl提供文件锁

struct flock {

….

short l_type;    /*Type of lock:F_RDLCK,F_WRLCK,F_UNLCK*/

short l_whence;  /*How to interpretl_start:SEEK_SET,SEET_CUR,SEEK_END*/

off_t l_start;     /*Starting offset for lock*/

off_t l_len;      /*Number of bytes to lock*/

pid_t l_pid;      /*PID of process blocking ourlock(F_GETLK only)*/

….

};

案例说明:


#include<stdio.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

void sys_err(char *str) {

perror(str);

exit(1);

}

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

int fd;

struct flock f_lock;

if(argc < 2) {

printf("./a.out filename\n");

exit(1);

}

if((fd = open(argv[1],O_RDWR)) < 0) {

sys_err("open");

}

//f_lock.l_type = F_WRLCK

f_lock.l_type = F_WRLCK;

f_lock.l_whence = SEEK_SET;

f_lock.l_start = 0;

f_lock.l_len = 0;  //0表示整个文件加锁

fcntl(fd,F_SETLKW,&f_lock);

printf("get flock\n");

sleep(10);

f_lock.l_type = F_UNLCK;

fcntl(fd,F_SETLKW,&f_lock);

printf("un flock\n");

close(fd);

return 0;

}

运行结果:

现象说明:当一个终端在运行的时候,同时打开另外一个终端,同时也执行./app test时发现开始的10秒内不允许操作,现象是test文件被锁住了。也就是说不能同时操作这个文件。

时间: 2024-11-07 14:11:42

5进程间锁:进程间pthread_mutex,文件锁的相关文章

Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信

目录 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 2.僵尸进程和孤儿进程 2.1僵尸进程 2.2孤儿进程 2.3僵尸进程如何解决? 3.互斥锁,锁 3.1互斥锁的应用 3.2Lock与join的区别 4.进程之间的通信 进程在内存级别是隔离的 4.1基于文件通信 (抢票系统) 4.2基于队列通信 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 1.创建进程的两种方式: 函数, 类. 2.pid: os.getpid() os.get

Linux间的进程通信;以及子进程的创建

1 "-----第六天-----------------------------------------------------------------------------" 2 3 1.版本控制:svn/git; 4 5 2.进程的概念: 6 1)程序和进程: 7 每个进程操作系统会为它分配 0-4G 的虚拟内存空间(32位操作系统): 其中0-3G为用户内存空间,进程可以对它进行读写操作: 3G - 4G 为系统内核空间,进程没有读写权限. 8 进程只能读写用户空间,没有权限读

ZeroMQ接口函数之 :zmq_inproc – &#216;MQ 本地进程内(线程间)传输方式

ZeroMQ API 目录 :http://www.cnblogs.com/fengbohello/p/4230135.html ————————————————————————————————————— ZeroMQ 官方地址:http://api.zeromq.org/4-2:zmq-inproc zmq_inproc(7)   ØMQ Manual - ØMQ/4.2.0 Name zmq_inproc – ØMQ 本地进程内(线程间)传输方式 Synopsis 进程内传输方式意味着在共享

在Windows系统上实现轻量级的线程间及进程间消息队列

看IaaS 资料时,捎带研究下硬件虚拟化,主要参考<基于intel VT-x 的Xen 全虚拟化实现>,<intel 开发手册 第三卷 19/20章> Intel VT 是intel X86架构的CPU硬件虚拟化技术,新增两种模式: VM root: 即虚拟机管理系统运行模式: VM non root:即虚拟机运行模式: 如下图: VMXON.VMXOFF用以实现打开或关闭虚拟化功能: VM Exit和VM Entry 用以实现non root和root之间的切换:这种转换被VMC

(转)进程间关系:进程、僵尸进程、孤儿进程、进程组、前台进程组、后台进程组、孤儿进程组、会话、控制终端

不同的shell对使用管道线时创建子进程的顺序不同,本文以bash为例,它是支持作业控制的shell的典型代表. 僵尸进程与孤儿进程 僵尸进程:先于父进程终止,但是父进程没有对其进行善后处理(获取终止子进程有关信息,释放它仍占有的资源).消灭僵尸进程的唯一方法是终止其父进程.孤儿进程:该进程的父进程先于自身终止.其特点是PPID=1(init进程的ID).一个孤儿进程可以自成孤儿进程组. 文中用到的缩写 PID = 进程ID (由内核根据延迟重用算法生成)PPID = 父进程ID(只能由内核修改

Android间的进程通讯(传递复杂对象)

Android间的进程通讯(传递复杂对象) 完成对复杂对象的序列化 在Android中传递复杂数据类型的时候要通过将序列化,在Android中提供了一个接口Parcelable来实现对对象的序列化. 下面对需要传输的对象进行序列化操作,首先看自定义的类Person. package com.example.service_parcelable_conmmute.bean; import android.graphics.Bitmap; /** * 用来传输的对象结构 * @author Xiny

Linux环境编程之进程(三):函数间跳转

引言:在编写程序时,经常在函数内部使用goto语句来跳转,从而进行出错处理,那么如果想要在函数之间进行跳转该怎么做呢?使用setjmp和longjmp函数. 给出示例程序: #include <stdio.h> #include <stdlib.h> #include <setjmp.h> static void f1(int, int, int, int); static void f2(void); static jmp_buf jmpbuffer; static

解决NSDistributedLock进程互斥锁的死锁问题(一)

在MAC下的多进程开发中,NSDistributedLock是一个非常方便的互斥锁解决方案,一般的使用方法: 12345678 NSDistributedLock *lock = [[NSDistributedLock alloc] initWithPath:@"/Users/mac/Desktop/lock.lock"];while (![lock tryLock]){ sleep(1);} //do something[lock unlock]; 但在实际使用过程中,当执行到do

守护进程,互斥锁,IPC,队列,生产者与消费者模型

小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某个任务,然而,如果主进程认为自己的事情一旦做完了就没有必要使用子进程了,就可以将子进程设置为守护进程 例如:在运行qq的过程,开启一个进程,用于下载文件,然而文件还没有下载完毕,qq就退出了,下载任务也应该跟随qq的退出而结束. from multiprocessing import Process

35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型

守护进程 进程:一个正在运行的程序. 主进程创建守护进程: 1.守护进程会在主进程代码执行结束后就终止, 2.守护进程内无法再开启子进程,否则抛出异常. 注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止. 例子:from multiprocessing import Processimport time def task(): print('老了....') time.sleep(2) print('睡了一会..') if __name__ == '__main__': prin