Linux高级 2019-6-1下午

1.进程互斥锁

1.1 与线程锁类型相同,也是 pthread_mutex_t 类型

1.2 修改线程锁属性,将其更改为进程锁

1.3 原子锁相关函数

  • pthread_mutexattr_t : 原子锁属性类型
  • pthread_mutexattr_inti(pthread_mutexattr_t*) : 初始化原子锁属性
  • pthread_mutexattr_destroy(pthread_mutexattr_t*) : 销毁原子锁属性
  • pthread_mutexattr_setpshared(pthread_mutexattr_t*, int pshared) : 更改原子锁属性

1.4 通过修改线程锁属性,使用进程锁完成父子进程对共享资源操作

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>

#define COUNT 5000

typedef struct
{
	int n_code;
	pthread_mutex_t process_lock;
}ProData;

int main()
{
	int fd;

	// 创建线程锁属性变量
	pthread_mutexattr_t attr;

	ProData* p_pro;

	fd = open("ProcessFile", O_RDWR|O_CREAT, 0664);
	ftruncate(fd, sizeof(ProData));
	p_pro = mmap(NULL, sizeof(ProData), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	bzero(p_pro, sizeof(ProData));

	// 修改属性
	pthread_mutexattr_init(&attr);
	pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);

	// 用户自定义互斥锁属性初始化互斥锁
	pthread_mutex_init(&(p_pro->process_lock), &attr);

	// 销毁线程锁属性
	pthread_mutexattr_destroy(&attr);

	pid_t pid;
	pid = fork();
	if(pid > 0)
	{
		for(int i=0; i<COUNT; i++)
		{
			pthread_mutex_lock(&(p_pro->process_lock));
			printf("Parent PID:%d\t++code:%d\n", getpid(), ++(p_pro->n_code));
			pthread_mutex_unlock(&(p_pro->process_lock));
		}
	}
	else if(pid == 0)
	{
		for(int i=0; i<COUNT; i++)
		{
			pthread_mutex_lock(&(p_pro->process_lock));
			printf("Child PID:%d\t++code:%d\n", getpid(), ++(p_pro->n_code));
			pthread_mutex_unlock(&(p_pro->process_lock));
		}
		exit(0);
	}
	else
	{
		perror("fork error");
		exit(0);
	}

	// 回收子进程
	pid_t wpid;
	wpid = wait(NULL);

	printf("Wait PID:%d\n", wpid);

	return 0;
}

2.文件锁

2.1 Linux中使用文件锁时一般可采用 lockf 或 fcntl 函数

2.2 lockf 为文件建议锁, fcntl 为可选择建议锁或强制锁

2.3 例子

#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("./ts 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_RDLCK;
	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;
}
  • 目前没懂该程序的作用

3.信号量

3.1 信号量分为一元灯、多元灯

3.2 一元灯创建过程

  • 1.定义信号量类型
  • 2.初始化信号量(设置灯值,灯值为1即为一元信号灯),信号量创建出的临界区通过灯值访问,只有灯值大于0时允许进入临界区,进入后灯值减1,使用临界区代码,使用完后将灯值加1;

3.3 使用信号量的一元灯与互斥锁没有区别(都是锁资源的)

3.4 多元灯(灯值大于1):用来锁流程业务

3.5 信号量函数

  • 有名信号量
  • 无名信号量(一般使用无名信号量)

4.死锁

4.1 概念

  • 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。
  • 简述:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。

4.2 使用线程同步技术要尽力避免死锁问题

4.3 死锁问题就是指多线程访问数据混乱,例如两个线程相互申请他人已占用的资源,导致操作阻塞

4.4 死锁的必要条件:

  • 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
  • 请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
  • 非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
  • 循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。

4.5 解决死锁的方式:

  • 1.服务者模式:每次使用全局变量之前都进行询问,可以使用则使用,否则继续等待;
  • 2.银行家模式:判断资源使用的风险,风险较大则拒绝使用,否则可以使用。

5.无锁编程与有锁编程的区别

  • 速度最快的是什么都没有的编程(基础编程);其次是无锁编程;最后是有锁编程(加锁解锁会消耗大量的时间资源);
  • 无锁编程无法再次进行优化,有锁编程可以进行再优化(减少锁的使用频率);
  • 无锁编程简单,易于实现,但是无法再优化。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值