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服务器时,会出现多个客户端同时像服务器传送文件的情况,需要根据发送的不同文件名创建新的接收文件,并要确立好调度顺序关系
- 实现代码
- 实验截图
思考题
- 对比单线程的版本的性能,并分析原因。
原因:单线程比较稳定易于实现,运行稳定。而多线程由于创建和切换的开销,采用多线程可能不会提高程序的执行速度,反而会降低速度,但是对于频繁IO操作的程序,多线程可以有效的并发。
实验中遇到的问题及解决办法
- 在对任务二进行编译时,出现error
解决办法:在对多线程进行更多学习后发现,多线程编译有所差别,需要利用
gcc XXX.c -lpthread -o XXXX
。在线程中我们一般采用Posix线程编程,而它所需的pthread
库不是不是Linux系统默认的库,连接时需要使用库libpthread.a
,所以在使用pthread_create创建线程时,在编译中要加-lpthread
参数。