【Linux系统编程】【Google面试题改编】线程之间的同步与协调 Linux文件操作

本文主要是介绍【Linux系统编程】【Google面试题改编】线程之间的同步与协调 Linux文件操作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

编写程序,有四个线程1、2、3、4

线程1的功能就是输1,线程2的功能就是输出2,以此类推……现在有四个文件ABCD初始都为空

现要让四个文件呈如下格式:

    A: 1 22 333 4444 1 22 333 4444…

    B: 22 333 4444 1 22 333 4444 1…

    C: 333 4444 1 22 333 4444 1 22…

    D: 4444 1 22 333 4444 1 22 333…

Linux C写的代码实现结果 

Linux C代码 

#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>int counter = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
char*files[]={"A", "B", "C", "D"};
int orders[4]={0,3,2,1};
int fds[4];
void *new(void *vptr) {int*p=(int*)vptr;int times=*p;for (int i = 0; i < 32; i++) {pthread_mutex_lock(&mutex); // 加锁while (counter%4 != times-1)pthread_cond_wait(&cond, &mutex);counter++;char buffer[16];for(int j=0;j<times;j++)buffer[j]=times+'0';buffer[times]=' ';write(fds[orders[(4-times+1+i)%4]],buffer,times+1);if(i==31)write(fds[orders[(4-times+1+i)%4]],"\n",1);pthread_cond_broadcast(&cond);pthread_mutex_unlock(&mutex); // 解锁}return NULL;
}int main(int argc, char **argv) {pthread_t threads[4];int times[4];for (int i = 0; i < 4; i++){times[i]=i+1;fds[i]=open(files[i],O_WRONLY|O_TRUNC);pthread_create(&threads[i], NULL, &new, &times[i]);}for (int i = 0; i < 4; i++)pthread_join(threads[i], NULL);pthread_mutex_destroy(&mutex); // 销毁互斥锁return 0;
}

 

首先创建四个空文件ABCD,要让四个线程协调工作需要用到互斥锁和条件变量,这里先声明初始化一下,并准备好四个文件的名字,orders等会解释用处,counter是用来计数区分四个线程的。

主函数创建了四个线程,需要让线程1打印一个1,线程2打印两个2,线程3打印3个3,线程4打印4个4,就需要向线程执行的函数传入一个参数来表示1234。这里使用了一个times数组而不是times整型变量,这是因为防止线程还没使用到正确的times值之前times又在下一次的循环中被修改了。打开四个文件准备写入,这里用的是只写和覆盖写。最后等待线程结束再退出。

在线程执行的函数中,先将指针转换为整型指针然后拿到整数的值,循环32次,这个循环次数无所谓,只是为了写多一点数据,每次循环中先加锁,然后判断counter和4取余是否等于打印*的次数减一,即判断是否轮到该线程输出,如果不是轮到该线程输出,那么该线程就进入等待,在某个线程输出完之后,counter++,同时唤醒所有等待线程并解锁。

然后接下来拼接出需要写入文件的字符串,然后最关键的地方来了,就是这个线程应该往哪个文件写这个字符串。

我们首先来观察一下我们需要达到的效果是怎么样的,首先得明白一个前提,即我们的线程是这样的:线程1打印一个1,线程2打印两个2,线程3打印3个3,线程4打印4个4。

那么线程1首先写文件A,完了写文件D,之后写文件C和文件D,从序数0开始计算的话,那么线程1写文件的顺序是这样的:0 3 2 1 0 3 2 1 0 3 2 1……

同时线程2写文件的顺序是这样的:1 0 3 2……,线程3写文件的顺序:2 1 0 3,线程4写文件的顺序:3 2 0 1,到这里就可以分析出来了,让一个数组int orders[4]={0,3,2,1},那么线程1写文件的顺序就是从第1个元素开始循环,而线程2写文件的顺序是从第4个元素开始循环,线程3写文件的顺序是从第3个元素开始循环,线程4写文件的顺序是从第2个元素开始循环,由此我们可以设计出代码实现。

编译运行程序,可见程序设计正确,成功按要求写入四个文件。

 怀疑我合起来输出造假,我再分开输出,合起来输出是为了好看和验证结果正确性。

这篇关于【Linux系统编程】【Google面试题改编】线程之间的同步与协调 Linux文件操作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/537964

相关文章

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3