# count_word
一个统计文本中单词有多少个的小脚本
更新了新的功能 - 计算每个单词一共出现多少次(并没有完全做对比,单词太多了。)
`gcc -o count count.c`
`./count a.txt`
# contacts
通讯录功能。
> gcc -o contacts contacts.c
>
> ./contacts
>
> 1. 输入用户 name & phone number
> 2. 打印刚刚所有插入的用户
> 3. delete 所输入的 用户
> 4. search 用户
> 5. save 用户至自定义文件
> 6. load 加载文件并读取里面的用户信息
# lock
基础的多线程编程,分别尝试使用了
> 互斥锁 mutex
>
> 自旋锁 spinlock
>
> 原子操作 \__asm__ volatile()
>
> gcc -o lock lock.c -lpthread
>
> ./lock
# pthread_pool
线程池的创建
注意 mutex & pthread_cond_wait() pthread_cond_broadcast() 等关键函数的调用
消化好本项目过程中接口之间的传递,线程之间的转换过程的写法和原理。
了解好 gdb 调试,学会如何使用 gdb
> gcc -o pthreadpool pthreadpool.c -lpthread -g
>
> ./pthreadpool
>
> `gdb 调试`
>
> ```powershell
> gcc -o pthreadpool pthreadpool.c -lpthread -g
>
> gdb ./pthreadpool
>
> b xxx(行) (breakpoint)
>
> b 124
>
> r (runing)
>
> c (continue)
> ```
# MySQL
> 创建数据库
>
> 使用数据库
>
> 创建表格
`gcc -o Mysql Mysql.c -I /user/include/mysql/ -lmysqlclient` `-I 系统头文件 -lmysqlclient: 引入我们编译中使用的库`
```
# include <mysql.h>
可能找不到
如果确实存在 /user/include/mysql/mysql.h
就改成
# include <mysql/mysql.h>
如果在上面的目录没有找到mysql.h文件,需要安装mysql-devel但是注意在ubuntu下安装mysql-devel命令:sudo apt-get install libmysqld-dev
如果你不想将#include<mysql.h>改成#include <mysql/mysql>的话,而且你是用的gcc编译的话,那么可以这样
gcc -I/user/include/mysql
# DELETE FROM TBL_USER WHERE U_NAME='Mayc'; # 提醒不安全,因为可能会同时有多条数据被删除
-- SET SQL_SAFE_UPDATES=0; # 设置成安全模式, 三条语句同时做
-- DELETE FROM TBL_USER WHERE U_NAME='Mayc';
-- SET SQL_SAFE_UPDATES=1;
sql -->
# 更好的方式
DELIMITER $$
CREATE PROCEDURE PROC_DELETE_USER(IN UNAME VARCHAR(32))
BEGIN
SET SQL_SAFE_UPDATES=0; # 设置成安全模式, 三条语句同时做
DELETE FROM TBL_USER WHERE U_NAME=UNAME;
SET SQL_SAFE_UPDATES=1;
END$$
CALL PROC_DELETE_USER('qiuxiang')
```
## 作业题:实现 MySQL 数据库的连接池
> 主要的思路还是根据之前的 pthread_pool 来进行改写。
>
> 需要注意的地方是,既然是多连接池,那么就肯定会应用到多线程。技术能力不够,在这里就没有再去做一个线程池配合,单纯的就是为每一个数据库连接配了一个线程 `threadid`。
>
> 我将整个过程分为如下几个部分:
>
> - 数据库连接结构体的创建
> - 用于管理数据库的相当于管理员的结构体,用来管理创建的数据库连接
> - 创建定量的数据库连接 --- 并且用链表连接管理,配合 `管理员` 结构体
> - 配合多线程进行并发处理,要注意临界资源的锁控制。
> - 将之前的 `mysql ` 的一些操作函数封装在 `struct tast` 结构体中,并作为任务分配给每一个数据库连接, 每有一个新的 `task` 需要唤醒一个数据库连接(等同于唤醒一个线程),或者说是从数据库连接池中取出一个空闲的连接。完成 `task` 之后要释放,也就是将一个数据库连接回收到连接池
# DNS-UDP
![](https://www.writebug.com/myres/static/uploads/2021/12/31/5903234aef04c23efafaa6b5de25a39e.writebug)
## Queries
> 查询名:
>
> 长度不固定,且不使用填充字节,一般该字段表示的就是需要查询的域名(如果是反向查询,则为 IP,反向查询即由 IP 地址反查域名),一般的格式如下图所示
![](https://www.writebug.com/myres/static/uploads/2021/12/31/fd35ac65fdf1c5afd52b08659685a0b8.writebug)
`0voice.com; name:60voice3com`
`www.0voice.com; name:3www60voice3com`
在网络中,就是将 `dns_head` 和 `dns_question` 两个结构体内的信息发送给 dns 服务器
![](https://www.writebug.com/myres/static/uploads/2021/12/31/2ad5d034c1952c9df1a63058be578ce6.writebug)
在 C/C++ 写网络程序的时候,往往会遇到字节的网络 l 顺序和主机顺序的问题。这是就可能用到 htonl(), ntohl(), ntohs(),htons()这 4 个函数。
网络字节顺序与本地字节顺序之间的转换函数:
htonl()--"Host to Network Long"
ntohl()--"Network to Host Long"
htons()--"Host to Network Short"
ntohs()--"Network to Host Short"
## function()
字符串切分 `strtok(string, delim)` -- `strtok(www.0voice.com, ".");`
- string -- 需要切分的字符串,
- delim -- 规则
在后续接着切分的时候变成 `strtok(nullptr, delim)`, 由此可发现,该函数是一个线程非安全函数
`strncpy(qname, token, len + 1)`
和 `strcpy()` 不同,`strncpy()` 需要指定长度
## sendto() 发送
### dns_client_commit(const char* domain)
dns 客户端比较固定的写法
```C
int dns_client_commit(const char* domain){
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0) return -1;
struct sockaddr_in servaddr = { 0 };
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(DNS_SERVER_PORT);
servaddr.sin_addr._addr = inet_addr(DNS_SERVER_IP);
struct dns_header header = { 0 };
dns_create_header(&header);
struct dns_question question = { 0 };
dns_create_question(question, domain);
char request[1024] = { 0 };
int length = dns_build_requestion(&header, question, request);
//request
sendto(fd, request, length, 0, servaddr, addr_len);
}
```
### dns_build_requestion(struct dns_header* header, struct dns_question* question, char* request, int rlen)
将 header 和 question 的数据打包并返回包长度
```C
int dns_build_requestion(struct dns_header* header, struct dns_question* question, char* request, int rlen){
if(header == nullptr || dns_question == nullptr || request == nullptr) return -1;
memset(request, 0, rlen);
// header --> request
memcpy(request, header, sizeof(struct dns_header));
int offset = sizeof(struct dns_header);
// question --> request
memcpy(request+offset, question->qname, question->length);
offset += question->length;
memcpy(requestion+offset, question->qtype, sizeof(question->qtype));
offset += sizeof(question->qtype);
memcpy(requestion+offset, question->qclass, sizeof(question->qclass));
offset += sizeof(question->qclass);
return offset;
}
```
## recvfrom() 接收
`send()` 和 `recvfrom()` 是一个流程的操作,属于同步操作,在 recvfrom()和 sendto()之间自动加锁,完成接收才结束
## UDP 和 TCP 相比,TCP 不具备的
1. UDP 传输速度快 (下载)
2. UDP 相应速度快 (游戏)
## 作业:DNS 异步查询
引入 `epoll`,以下是 `epoll` 的接口介绍
### epoll 接口
1. `int epoll_create(int size);`
创建一个 `epoll` 的句柄,`size` 用来告诉内核这个监听的数目一共有多大。这个参数不同于 `select()` 中的第一个参数,给出最大监听的 `fd+1` 的值。需要注意的是,当创建好 `epoll` 句柄后,它就是会占用一个 `fd` 值,在 `linux` 下如果查看 `/proc/` 进程 `id/fd/`,是能够看到这个 `fd` 的,所以在使用完 `epoll` 后,必须调用 `close()` 关闭,否则可能导致 fd 被耗尽。(这里我就遇到了相反的麻烦,提前把 `epoll` 给关闭了)
2. `int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);`
`epoll` 的事件注册函数,它不同与 `select()` 是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。第一个参数是 `epoll_create()` 的返回值,第二个参数表示动作,用三个宏来表示:
- EPOLL_CTL_ADD:注册新的 fd 到 epfd 中;
- EPOLL_CTL_MOD:修改已经注册的 fd 的监听事件;
- EPOLL_
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
100012227-基于C语言实现多线程和线程池.zip (43个子文件)
learning_project
mysql_pool
Mysql_pool.c 10KB
myc_db.sql 924B
0voice.jpg 36KB
TCP_高并发
tcp_server.c 3KB
tcp_client.c 3KB
Contacts
contacts.c 6KB
Count_word
count_word.c 1KB
a.txt 118B
b.txt 601KB
MySQL
Mysql.c 6KB
myc_db.sql 956B
epoll_websocket
epoll_websocket.c 10KB
websocket.html 1KB
pthread_pool
线程池使用场景与原理分析.md 5KB
threadpool.c 4KB
设计模式
designpattern
decorator1.cpp 1KB
proxy.cpp 1KB
template2.cpp 1KB
factoryabstract.cpp 4KB
chain_of_resp1.cpp 589B
factory2.cpp 2KB
observer1.cpp 894B
factory3.cpp 2KB
adapter.cpp 1KB
chain_of_resp2.cpp 2KB
template1.cpp 636B
factory1.cpp 998B
strategy1.cpp 457B
observer2.cpp 1KB
strategy2.cpp 1KB
decorator2.cpp 2KB
LICENSE 1KB
dns
3.png 20KB
dns.c 6KB
1.png 198KB
2.png 36KB
Lock
lock.c 1KB
TCP_EPOLL
Tcp_server.c 3KB
image-20201210213520326.png 61KB
ASYNC_DNS
async_dns.c 10KB
README.md 50KB
Http
image-20201210163839827.png 121KB
http_request.c 2KB
共 43 条
- 1
资源评论
- m0_739195612023-08-10果断支持这个资源,资源解决了当前遇到的问题,给了新的灵感,感谢分享~
神仙别闹
- 粉丝: 2671
- 资源: 7640
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- HITK0203MP-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- HITK0202MP-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说
- 电子电气工程师使用的单位和符号
- HITK0201MP-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- MyBatis动态SQL:构建灵活查询的利器.md
- HITJ0303MP-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- tesseract安装包
- 1_32陀螺仪舵机.zip
- HITJ0302MP-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- XILINXFPGA源码PCIExpress标准概述
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功