【github myLocker】select监听多个fd,互斥锁保护终端交互
来源:互联网 发布:淘宝服装模特摄影 编辑:程序博客网 时间:2024/06/15 23:15
select监听多个fd
select用于多个fd的管理,检测哪个fd可读、可写,如果可读则接收消息(读),如果可写则输出消息(写)。
相关的函数:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);void FD_CLR(int fd, fd_set *set); /* 将某个fd从集合set中删除 */int FD_ISSET(int fd, fd_set *set); /* 检测fd是否还在集合set中 */void FD_SET(int fd, fd_set *set); /* 将fd加入集合set中 */void FD_ZERO(fd_set *set); /* 将集合set清空 */
其中,select函数的选项timeout很有用,当其是NULL时,函数无限期阻塞;当其是{0,0}时,立即返回结果;当其是某一个大于0的时间值时,表示一定时间后return。
关于timeout:
struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */};
应用:
fd_set readfds; struct timeval tv = {0,0}; while(1){ memset(buff,0,BUFF_LEN); FD_ZERO(&readfds); FD_SET(main_send_fd,&readfds); FD_SET(main_lock_fd,&readfds); if(select(FD_SETSIZE,&readfds,NULL,NULL,&tv) <= 0){ continue; } if(FD_ISSET(main_send_fd,&readfds)){ ret = recvfrom(main_send_fd,buff,BUFF_LEN,0,(struct sockaddr *)&client_addr,&client_addr_len); if(ret > 0){ //... } } else if(FD_ISSET(main_lock_fd,&readfds)){ ret = recvfrom(main_lock_fd,buff,BUFF_LEN,0,(struct sockaddr *)&locker_addr,&locker_addr_len); if(ret > 0){ //... } } }
互斥锁保护终端交互
程序运行,未使用读写锁的情况下,输出信息是杂乱的,提示信息的输出和用户的输入被打断分开了。
如下:
[textRWThread] ret: 13, recv buff: write to .key[lockerThread] ret: 7, recv buff: encrypt[lockerThread] start encrypt text file...[lockerThread] please enter filename to enrypt which file is put in folder:[main] main recv "write ok" from pthTextRW.[textCodeThread] pthTextCode -> main "prime numbers created" ok.txt[lockerThread] the file need to encrypt is folder/txt[lockerThread] encrypt work finished.[main] main recv "encrypt ok" from pthLocker.[main] encrypt and prime number write work all finished![main] retval from textCode thread: 1[main] retval from textRW thread: 1[main] retval from Locker thread: 1
注意4-7行,当lockerThread
线程输出please enter filename to enrypt which file is put in folder.
要求用户输入文件名时,另外两个线程main
, textCodeThread
在屏幕上输出了信息,然后用户的输入文件名明显和LockerThread
的提示信息分割开来。于是我们有这样的需求:怎样让提示信息的输出和文件名的输入成为一个原子操作(不可分割)。从本质上讲,线程都是在向屏幕写东西,这是典型的多人使用打印机问题。读写锁适用于读的次数多于写的次数,互斥锁则适用于多人使用同一资源的问题。
互斥锁的相关函数:
int pthread_mutex_destroy(pthread_mutex_t *mutex);int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);
互斥锁在使用完毕后,必须要对互斥锁进行销毁,以释放资源。即调用pthread_mutex_destroy()
函数。
因为工程中的情况复杂,在屏幕上输入和输出,我们不能直接定义一个函数在函数里面上锁、解锁,再用线程调用此函数来实现不同线程独享stdout, stderr的资源,但是可以用全局变量mutex来实现上锁和阻塞,当一个线程已经对它上锁了,另一个线程试图再次上锁就会block。
code:
public.h:
pthread_mutex_t mutex_output;
main.c:
pthread_mutex_init(&mutex_output,NULL); //初始化/* 给输出动作上锁,然后解锁 */pthread_mutex_lock(&mutex_output);pthPrint();printf("recv msg \"prime numbers created!\"\n");pthread_mutex_unlock(&mutex_output);...pthread_mutex_destroy(&mutex_output); /* 销毁互斥锁 */
pthTextCode.c输出的上锁情况和main类似。
pthLocker.c:
/* 给一个连续的输出和输入动作上锁,然后解锁 */ pthread_mutex_lock(&mutex_output);pthPrint();printf("please enter filename to enrypt which file is put in folder: \n");scanf("%s",filename);pthread_mutex_unlock(&mutex_output);
之后的效果:
工程地址:https://github.com/theArcticOcean/myLocker
- 【github myLocker】select监听多个fd,互斥锁保护终端交互
- select监听多个socket的例子
- select监听多个客户端 -- linux函数
- 利用select/poll监听多个设备详解
- layui-form表单自定义监听多个select
- 关于select和FD
- 为什么select只能监听1024个
- 【github myLocker】线程返回值,重复引用头文件,二进制文件I/O
- 【github myLocker】线程切换调试,读写指针修改文件,socket 阻塞设置
- 多个线程如何操作同一个epoll fd
- 多个线程如何操作同一个epoll fd
- 多个线程如何操作同一个epoll fd
- select 监听
- 多个Button监听
- 多个listview监听
- 多个按钮监听
- 深入解析为何select最多只能监听1024个
- 用户使用键盘循环输入字符,select监听终端,将用户输入的字符输出到终端上
- NYOJ题目36-最长公共子序列(经典动态规划题)
- shell解析命令行的过程以及eval命令
- 初识scala
- Qt+ffmpeg仿格式工厂:编程中遇到的问题(三)
- 51nod1265判断四点共面
- 【github myLocker】select监听多个fd,互斥锁保护终端交互
- 设计模式之---命令模式
- CSS中关于触发BFC
- EasyDSS高性能流媒体服务器前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间
- 理解高并发(20).大白话阿姆达尔定律
- 机器学习第九课(bagging,随机森林,样本不均衡)
- 各大公司对于java求职者的要求,你值得一看
- Thinkphp 模型->区间查询
- Test...