zoukankan      html  css  js  c++  java
  • 实验三《并发程序》

    实验三《并发程序》

    并发程序1

    学习使用Linux命令wc(1)

    基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端

    客户端传一个文本文件给服务器

    服务器返加文本文件中的单词数

    wc命令

    Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数、字数、行数,并将统计结果显示输出。- c 统计字节数,- l 统计行数,- w 统计字数。参考Linux下wc命令详解

    在实现wc命令的过程中出现了如下问题:

    1. 对于字数的概念完整性问题,wc中对字数的定义是由空格字符区分开的最大字符串,而我的理解是由空格键隔开的字符串,导致我对字数的统计不准确。对于test1.txt文件,wc命令统计的字数是1576,而我的结果是3486.
    2. 输出的时候,注意格式控制,否则统计结果会混合在一起。

    如图所示:

    image

    解决方法:字数统计中需要特别注意的是,当读到一个空格的时候,有两种情况:

    1、前面一个字符也是空格(或回车),这时不能将字数加一。

    2、前面一个字符不是空格,这时认为字数加一。

    如何才能实现上面所说的区别呢?最自然的办法就是再找一个变量记录一下。

    这里我通过inspace这个变量记录前一个字符的状态,如果前一个字符是空格或者回车,就将inspace置1,其他字符就置0;在读到一个空格时,判断inspace,当inspace为0时,才表示一个字结束,将字数w++。

    修改后的核心代码如下:

    while((t=fgetc(in))!=EOF)
    	{
    		if((t==' ')&&(inspace==0))
    		{
                           w++;
                           m++;
                           inspace=1;	
    		}
    		else if(t=='
    ')
    		{
    			l++;
                            m++;
                            inspace=1;
    		}
    		else{
                    m++;	
                    inspace=0;
                    }
    	}
    

    具体完整代码见码云

    客户端和服务器文件传输

    之前我们已经实现了,具体内容见我的另一篇博客。daytime服务器——客户端

    这里我们需要考虑的是如何传输文件。

    最直接想到的办法就是将文件读入一个buffer然后传到客户端。

    具体代码见码云,最终实现效果如下图。

    image

    并发程序2

    使用多线程实现wc服务器并使用同步互斥机制保证计数正确,对比单线程版本的性能,并分析原因。

    多线程互斥机制

    线程就是运行在进程上下文中的逻辑流

    一个进程里允许同时运行多个线程程序。线程由内核自动调度。每个线程都有自己的线程上下文。所有运行在一个进程里的线程共享该进程的整个虚拟空间。

    信号量提供了一种很方便的方法来确保对共享变量的互斥访问。基本思想是将每个共享变量与一个信号量联系起来,然后用PV操作将相应临界区包围起来。

    互斥锁适用于同时可用的资源是唯一的情况;信号量适用于同时可用的资源为多个的情况。

    互斥锁机制主要包括以下基本函数:

    ● 互斥锁初始化:pthread_mutex_init()

    ● 互斥锁上锁:pthread_mutex_lock()

    ● 互斥锁判断上锁:pthread_mutex_trylock()

    ● 互斥锁解锁:pthread_mutex_unlock()

    ● 消除互斥锁:pthread_mutex_destroy()

    信号量就是操作系统中多用到的PV原子操作,它广泛应用于进程或线程间的同步与互斥。信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。

    Linux实现了Posix的无名信号量,主要用于线程间的互斥与同步。这里主要介绍几个常见函数:

    ● sem_init()用于创建一个信号量,并初始化它的值。

    ● sem_wait()和sem_trywait()都相当于P操作,在信号量>0时,它们能将信号量的值减1。两者的区别在于信号量<0时,sem_wait(0将会阻塞进程,而sem_trywait则会立即返回。

    ● sem_post()相当于V操作,它将信号量的值加1,同时发出信号来唤醒等待的进程。

    ● sem_getvalue()用于得到信号量的值。

    ● sem_destroy()用于删除信号量。

    根据书上P695的例子(基于线程的并发服务器),参考我的另一篇博客并发的daytime服务器

  • 相关阅读:
    【笔记】模电lesson04 晶体管
    [笔记]模电如何判断和识别二极管的正负极
    [笔记]模电用数字万用表判断三极管管脚
    【笔记】模电lesson06 放大电路分析方法I
    【笔记】模电lesson07 放大电路分析方法II
    【翻译】在Verilog设计中使用参数化模块库(Quartus II)(Verilog)
    【原创】DE2实验练习解答—lab5 Clocks and Timers 【Verilog】【Digital Logic】
    【笔记】模电lesson 02 常用半导体器件
    【翻译】modelsim指南 I 之基本仿真(digital logic)
    【原创】DE2 实验练习解答—lab 2:数字和显示(digital Logic)(DE2)
  • 原文地址:https://www.cnblogs.com/clever-universe/p/7862843.html
Copyright © 2011-2022 走看看