实验三《并发程序》

并发程序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=='\n')
		{
			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服务器

posted on 2017-11-19 23:07  20155225江智宇  阅读(330)  评论(2编辑  收藏  举报