2018-2019-1 20165330 实验三 实时系统

任务一

任务详情
  • 学习使用Linux命令wc(1)
  • 基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端
  • 客户端传一个文本文件给服务器
  • 服务器返加文本文件中的单词数
实现wc命令
  • 命令参数
    • -c:统计字节数
    • -l:统计行数
    • -m:统计字符数。这个标志不能与 -c 标志一起使用。
    • -w:统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串
    • -L:打印最长行的长度
    • -help:显示帮助信息
    • --version:显示版本信息
  • 实现伪代码
      int main()
      {
         fd = fopen()//打开文件;
         fscanf()//对文件的内容以字符串的形式进行读取
         if..count++//设置条件,当满足字符串条件时计数;
      }
    
    • 对于wc -w功能与我们统计单词个数相似,而其实现时:由' ','\n','\t','\r'作为分隔符
    • 统计单词个数时,除上述分隔符,还加入了文本文件中常见的符号:'!','"','?','.',',','(',')',':',';','-'作为分隔符
  • 实现wc -w
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFERSIZE 1024

int main()
{
    FILE *fp;
    char ch;
    char filename[100];
    int flag=0,num=0;
        printf("input filename: ");
    scanf("%s",filename);
    if((fp = fopen(filename,"r"))==NULL)
    {
        printf("Failure to open %s\n",filename);
        exit(0);
    }
    while((ch=fgetc(fp))!=EOF)
    {
        if(ch==' ' || ch=='\n' || ch=='\t' || ch=='\r')
        {
            flag=0;
        }
        else
        {
            if(flag==0)
            {
                flag=1;
                num++;
            }

        }

    }
    printf("%c\n",num+48);
    fclose(fp);
    return 0;
}
  • 实现单词个数统计
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFERSIZE 1024
/*int num=0;
void wc(char buffer[],int size)
{
    int i,flag=0;
    for(i=0;i<size;i++)
    {
        if(buffer[i]==' ' || buffer[i]=='\n' || buffer[i]=='\t' || buffer[i]=='\0' || buffer[i]=='!' || buffer[i]=='?' || buffer[i]=='"' || buffer[i]=='.' || buffer[i]== ',' || buffer[i]==':' || buffer[i]=='(' || buffer[i]==')' || buffer[i]==';' || buffer[i]=='■ ' || buffer[i]=='•' )
        {
            flag=0;
        }
        else
        {
            if(flag==0)
            {
                num++;
            }
            flag=1;
        }
    }
    return num;
}*/
int main()
{
    FILE *fp;
    char ch;
    char filename[100];
    int flag=0,num=0;
        printf("input filename: ");
    scanf("%s",filename);
    if((fp = fopen(filename,"r"))==NULL)
    {
        printf("Failure to open %s\n",filename);
        exit(0);
    }
    while((ch=fgetc(fp))!=EOF)
    {
        if(ch==' ' || ch=='\n' || ch=='\t' ||  ch=='\!' || ch=='\?' || ch=='\"' || ch=='\.' || ch== '\,' || ch=='\:' || ch=='\(' || ch=='\)'     || ch=='\;' || ch=='\-')
        {
            flag=0;
        }
        else
        {
            if(flag==0)
            {
                flag=1;
                num++;
            }

        }

    }
    printf("%d\n",num);
    fclose(fp);
    return 0;
}
文件传输实现单词个数统计

任务二

任务详情
  • 使用多线程实现wc服务器并使用同步互斥机制保证计数正确
多线程
  • 同步
    • 直接制约关系
    • 加入同步机制主要是为了在多线程程序中,如果需要对某个共享资源C进行同步访问,如果系统没有调度到B,A也是没有可能访问C的,必须等B调度到之后,A才可能重新访问。
  • 互斥锁
    • 主要用来保护临界资源
    • 临界资源,就是有可能多个线程都需要访问的数据地址,也有可能是某一段代码,执行这段代码有可能会改变多个线程都需要访问的数据。
  • 多线程实现wc服务器时,会出现多个客户端同时像服务器传送文件的情况,需要根据发送的不同文件名创建新的接收文件,并要确立好调度顺序关系
  • 实现代码
  • 实验截图
    image
思考题
  • 对比单线程的版本的性能,并分析原因。

原因:单线程比较稳定易于实现,运行稳定。而多线程由于创建和切换的开销,采用多线程可能不会提高程序的执行速度,反而会降低速度,但是对于频繁IO操作的程序,多线程可以有效的并发。

实验中遇到的问题及解决办法

  • 在对任务二进行编译时,出现error

解决办法:在对多线程进行更多学习后发现,多线程编译有所差别,需要利用gcc XXX.c -lpthread -o XXXX 。在线程中我们一般采用Posix线程编程,而它所需的pthread库不是不是Linux系统默认的库,连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时,在编译中要加-lpthread参数。

posted @ 2018-11-16 17:00  20165330张羽昕  阅读(140)  评论(0编辑  收藏  举报