linux系统和网络(三):IO,信号,信号量,线程

news2024/10/1 3:26:47

        本文主要探讨linux的IO,信号,信号量,线程相关知识,详细知识可参考本博客其他文章。

信号(可参考本博客其他文章)
        信号是内容受限的异步通信机制,硬件异常后统内核发出信号

         alarm产生SIGALARM信号,读端关闭后管道write产生SIGPIPE信号

常见信号
SIGINT             2         Ctrl+C(前台进程组中每个进程)
SIGABRT            6         异常终止
SIGPOLL   SIGIO    8         异步IO
SIGKILL            9         杀死进程
SIGSEGV            11        无效存储访问信号
SIGPIPE            13        管道,socket
SIGALARM           14        alarm
SIGTERM            15        kill命令默认
SIGCHLD            17        子进程终止(父进程接收信号)
SIGUSR1            10        自定义信号
SIGUSR2            12        自定义信号

        信号处理

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

默认处理SIG_DFL
忽略处理SIG_IGN
捕获处理handler
返回出错为SIG_ERR
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
struct sigaction {
               void     (*sa_handler)(int);
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);
           };

        sigaction可设置新捕获函数和获取旧的捕获函数,signal须在新捕获函数中获取旧捕获函数


        alarm和pause

                alarm内核提供闹钟的API

unsigned int alarm(unsigned int seconds);
int pause(void);

                内核挂起,进程暂停运行,交出CPU给其他进程(阻塞住),需被信号唤醒

信号量(可参考本博客其他文章)

sem_t sem; 
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
sem:信号量,pshared:0线程间非0用于进程,value:信号量初值

IO
        阻塞IO:wait、pause、sleep、read、write等
        非阻塞IO访问:添加O_NONBLOCK模式(fd调用fcntl)
        select和poll(多路复用IO):外部阻塞式,内部非阻塞式自动轮询多路阻塞式IO

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
               int   fd;         /* 文件描述符*/
               short events;     /* 监控事件 */
               short revents;    /* 监控事件中满足条件的返回事件*/
           };

POLLIN普通或带外优先数据可读,即POLLRDNORM | POLLRDBAND
POLLRDNORM 数据可读
POLLRDBAND 优先级带数据可读
POLLPRI 高优先级可读数据
POLLOUT普通或带外数据可写
POLLWRNORM 数据可写
POLLWRBAND 优先级带数据可写
POLLERR 发生错误
POLLHUP 发生挂起
POLLNVAL 描述字不是一个打开的文件

nfds:监控文件描述符个数

timeout:等待(ms),-1阻塞等,0:不阻塞进程,>0等待指定毫秒数
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

nfds:监控文件描述符个数

struct timeval {
               long    tv_sec;         /* seconds */
               long    tv_usec;        /* microseconds */
           };

       and

           struct timespec {
               long    tv_sec;         /* seconds */
               long    tv_nsec;        /* nanoseconds */
           };

FD_ZERO(fd_set* fdset): 将fd_set位初始化为0
FD_SET(int fd, fd_set* fdset):注册文件描述符fd信息
FD_CLR(int fd, fd_set* fdset):清除文件描述符fd信息
FD_ISSET(int fd, fd_set* fdset):fd_set包含文件描述符fd信息返回真

        异步IO(操作系统中断)
        存储映射IO(mmap):共享内存,提高效率(LCD显示和IPC间共享内存)

线程(可参考本博客其他文章)
        进程:CPU时分复用,实现多任务系统需求,进程间切换开销大,通信效率低
        线程间通信效率高且可多任务

        线程函数
                线程创建,退出,回收,分离,id

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
void pthread_exit(void *retval);
int pthread_join(pthread_t thread, void **retval);
int pthread_detach(pthread_t thread);
pthread_t pthread_self(void);

线程退出后,主线程pthread_join回收子线程,pthread_detach是线程分离,子线程自回收

 
                取消线程

int pthread_cancel(pthread_t thread);

线程取消状态
int pthread_setcancelstate(int state, int *oldstate);
PTHREAD_CANCEL_ENABLE:线程可取消(默认值)
PTHREAD_CANCEL_DISABLE:线程不可取消,取消请求挂起至线程状态为 PTHREAD_CANCEL_ENABLE

线程取消性类型
int pthread_setcanceltype(int type, int *oldtype);
PTHREAD_CANCEL_DEFERRED:取消请求到达,线程继续运行,取消请求挂起,直到线程到达取消点(默认)
PTHREAD_CANCEL_ASYNCHRONOUS:立即取消

线程清理函数中添加和移除清理函数
void pthread_cleanup_push(void (*routine)(void *),void *arg);
void pthread_cleanup_pop(int execute);
routine:清理函数,arg给清理函数传参
execute为0清理函数不调用且清理函数栈中最顶层函数移除,非0还清除清理该函数
线程清理函数中添加(入栈)和清理(出栈)次数相同

                互斥量(代码保护)

pthread_mutex_t mutex;
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);


                线程条件

pthread_cond_t  cond;
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);

demo1:

              linux的sleep命令

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void func(int sig)
{

}

void my_sleep(unsigned int sec)
{
        struct sigaction act = {0};
        act.sa_handler = func;
        sigaction(SIGALRM, &act, NULL);
        alarm(sec);
        pause();
}


int main(int argc,char *argv[])
{
        if(argc != 2)
                printf("ex: ./a.out sec");
        printf("my_sleep start\n");
        my_sleep(atoi(argv[1]));
        printf("my_sleep end\n");

        return 0;
}

结果显示:  

demo2: 

        多路io(poll)监控鼠标和键盘

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>

int main(void)
{
        int fd;
        int ret;
        char buf[256];
        struct pollfd fds[2] = {0};

        fd = open("/dev/input/mouse0", O_RDONLY);
        if (fd < 0)
        {
                perror("open");
                return -1;
        }

        fds[0].fd = 0;
        fds[0].events = POLLIN;

        fds[1].fd = fd;
        fds[1].events = POLLIN;

        ret = poll(fds,2, 10000);
        if (ret < 0)
        {
                perror("poll");
                return -1;
        }
        else if (ret == 0)
        {
                printf("timeout\n");
        }
        else
        {
                if (fds[0].events == fds[0].revents)
                {
                        memset(buf, 0, sizeof(buf));
                        read(0, buf, 5);
                        printf("keyboard:%s\n", buf);
                }

                if (fds[1].events == fds[1].revents)
                {
                        memset(buf, 0, sizeof(buf));
                        read(fd, buf, 50);
                        printf("mouse:%s\n", buf);
                }
        }

        return 0;
}

结果显示:

        多路io(select)监控鼠标和键盘 

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>


int main()
{
        int fd;
        int ret;
        char buf[256];
        fd_set set;
        struct timeval tm;

        fd = open("/dev/input/mouse0", O_RDONLY);
        if (fd < 0)
        {
                perror("open:");
                return -1;
        }

        FD_ZERO(&set);
        FD_SET(fd, &set);
        FD_SET(0, &set);

        tm.tv_sec = 10;
        tm.tv_usec = 0;

        ret = select(fd+1, &set, NULL, NULL, &tm);
        if (ret < 0)
        {
                perror("select");
                return -1;
        }
        else if (ret == 0)
        {
                printf("timeout\n");
        }
        else
        {
                if (FD_ISSET(0, &set))
                {
                        memset(buf, 0, sizeof(buf));
                        read(0, buf, 5);
                        printf("keyboard:%s\n", buf);
                }

                if (FD_ISSET(fd, &set))
                {
                        memset(buf, 0, sizeof(buf));
                        read(fd, buf, 50);
                        printf("mouse:%s\n", buf);
                }
        }

        return 0;
}

结果显示:

        异步IO监控鼠标和键盘 (可配合poll.selectshi用)

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

int mouse_fd;

void func(int sig)
{
        char buf[200] = {0};

        if (sig != SIGIO)
                return;

        read(mouse_fd, buf, 50);
        if(strlen(buf))
                printf("mouse:%s\n", buf);
}

int main()
{
        char buf[200];
        int flag = -1;

        mouse_fd = open("/dev/input/mouse0", O_RDONLY);
        if (mouse_fd < 0)
        {
                perror("open:");
                return -1;
        }

        //获取 mouse_fd
        flag = fcntl(mouse_fd, F_GETFL);
        //add O_ASYNC(异步)
        flag |= O_ASYNC;
        //重写 mouse_fd
        fcntl(mouse_fd, F_SETFL, flag);
        //设置 mouse_fd 接收SIGIO/SIGURG信号且与进程绑定
        fcntl(mouse_fd, F_SETOWN, getpid());

        signal(SIGIO, func);

        while (1)
        {
                memset(buf, 0, sizeof(buf));
                read(0, buf, 5);
                if(strlen(buf))
                        printf("keyboard:%s\n", buf);
        }

        return 0;
}

结果显示:

demo3: 

        字符输入和个数计算(线程+信号量)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

char buf[256] = {0};
sem_t sem;
unsigned int flag = 0;


void *func(void *arg)
{
        sem_wait(&sem);
        while (flag == 0)
        {
                printf("the num of string :%ld\n", strlen(buf));
                memset(buf, 0, sizeof(buf));
                sem_wait(&sem);
        }

        pthread_exit(NULL);
}


int main(void)
{
        int ret;
        pthread_t th;

        sem_init(&sem, 0, 0);

        ret = pthread_create(&th, NULL, func, NULL);
        if (ret != 0)
        {
                printf("pthread_create error\n");
                exit(-1);
        }

        printf("input string:\n");
        while (scanf("%s", buf))
        {
                if (!strncmp(buf, "end", 3))
                {
                        printf("process end\n");
                        flag = 1;
                        sem_post(&sem);
                        break;
                }

                sem_post(&sem);
        }

        ret = pthread_join(th, NULL);
        if (ret != 0)
        {
                printf("join error\n");
                exit(-1);
        }

        printf("join sucess\n");
        sem_destroy(&sem);

        return 0;
}

结果显示:

         字符输入和个数计算(线程条件)

结果显示: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1333002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FHE简介

1. 引言 加密技术已经存在了数千年&#xff0c;用于相互发送秘密信息。例如&#xff0c;凯撒密码是最早的加密技术之一&#xff0c;可以追溯到公元前60年&#xff0c;其只由字母表中的字母交换组成。 随着互联网的出现&#xff0c;人们生成的私人数据量呈指数级增长&#xff…

第11章 GUI Page429~430 步骤八 支持“十字”形

运行效果&#xff1a; 关键代码&#xff1a; 新增头文件&#xff1a; //item_cruciform.hpp #ifndef ITEM_CRUCIFORM_HPP_INCLUDED #define ITEM_CRUCIFORM_HPP_INCLUDED#include <cmath> #include "item_line.hpp"class CruciformItem : public IItem { pub…

图像识别SLIC、Haralick texture features(自备)

SLIC 简单线性迭代聚类(SLIC ),它采用k-means聚类方法来有效地生成超像素。 SLIC超像素分割详解&#xff08;一&#xff09;&#xff08;二&#xff09;&#xff08;三&#xff09;_超像素分割 样本-CSDN博客 超像素分割 & SLIC算法 & 使用示例_slic分割算法matlab-C…

C语言、c++实现超好玩植物大战僵尸(完整版附源码)

实现这个游戏需要Easy_X main.cpp //开发日志 //1导入素材 //2实现最开始的游戏场景 //3实现游戏顶部的工具栏 //4实现工具栏里面的游戏卡牌 #define WIN_WIDTH 900 #define WIN_HEIGHT 600 //定义植物类型 enum { WAN_DOU, XIANG_RI_KUI, ZHI_WU_COUNT }; #include<stdio.…

SpringMVC:整合 SSM 中篇

文章目录 SpringMVC - 04整合 SSM 中篇一、优化二、总结三、说明注意&#xff1a; SpringMVC - 04 整合 SSM 中篇 一、优化 在 spring-dao.xml 中配置 dao 接口扫描&#xff0c;可以动态地实现 dao 接口注入到 Spring 容器中。 优化前&#xff1a;手动创建 SqlSessionTempl…

『OPEN3D』1.1 点云处理

目录 1.open3d中的点云IO 2.点云的可视化 3 点云voxel下采样 4. 顶点法线估计 5.最小外界矩 6. 凸包计算 7. 点云距离计算 8. DBSCAN clustering聚类 9. RANSAC(Random Sample Consensus) 10. 点云平面分割 11. 隐藏点移除 12.outliers移除 13 最远点采样&#xf…

视频编码码率控制

什么是码率控制 码率控制是编码器的一个重要模块&#xff0c;主要的作用就是用算法来控制编码器输出码流的大小。虽然它是编码器的一个非常重要的部分&#xff0c;但是它并不是编码标准的一部分&#xff0c;也就是说&#xff0c;标准并没有给码控设定规则。我们平时用的编码器…

sql_lab之sqli注入中的cookie注入

Cookei注入&#xff08;gxa的从cookei注入&#xff09; 1.打开控制台 2.验证id2时的值 document.cookie"id2" 3.判断是上面闭合方式 document.cookie"id2 -- s" 有回显 说明是’单引号闭合 4.用order by 判断字段数 5.用联合查询判断回显点 接下来的…

html5 实现网页截屏 页面生成图片

效果 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"referrer" content"no-referrer" /><meta name"viewport"content"widthdevice-width,intial-sc…

前端开发新趋势:Web3 与虚拟现实的技术融合

在当今互联网技术日新月异的时代&#xff0c;Web技术也在不断地发展和变革。从前端开发的角度来看&#xff0c;新技术的涌现和旧技术的迭代让前端开发者们面临着前所未有的挑战和机遇。Web3 与虚拟现实&#xff08;VR&#xff09;的技术融合&#xff0c;正是当前前端开发领域的…

dpc与线程切换

中断服务例程 延迟过程调用 线程切换 键盘信号传输 1. 背景 我一般用ctrlaltdel能否呼出winlogon桌面作为Windows卡死&#xff08;hang&#xff09;还是个别程序卡死的鉴别手段。因为一则用户态的程序没办法干扰这个呼出流程&#xff0c;二则如果不能呼出任务管理器来终止进程…

openmediavault基本操作

omv基本操作 使用hostname访问共享文件夹设置1.挂载磁盘2.提交更改3.新建用户4.建立共享文件夹5.设置SMB/CIFS服务7.测试7.1.速度测试 使用hostname访问 把网口和wifi设置成DHCP,使用hostname访问,这样把NAS拿到任何地方都不需要配置了,自动联网进行访问. #网络->常规 #设…

搭建谷歌 Gemini,体验谷歌版GPT4

12.06 日谷歌 DeepMind CEO 和联合创始人 Demis Hassabis 正式推出了大模型Gemini 目前&#xff0c;Gemini 1.0 提供了三个不同的尺寸版本&#xff0c;分别如下&#xff1a; Gemini Ultra&#xff1a;规模最大、能力最强&#xff0c;用于处理高度复杂的任务&#xff1b;Gemin…

map容器的基本使用

文章目录 mapmap模板参数默认构造迭代器[ ]{ }inserterasefindlower_bound && upper_boundcountequal_range map和set容器&#xff0c;multimap和multiset是树形结构的关联式容器&#xff0c;这四种容器底层原理都是红黑树&#xff0c;容器中的元素是一个有序序列。 ma…

电子电器架构(E/E)演化 —— 主流主机厂域集中架构概述

电子电器架构(E/E)演化 —— 主流主机厂域集中架构概述 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。…

存储卡显示0字节怎么办?恢复0字节的存储小技巧

存储卡显示0字节是一个常见的故障现象&#xff0c;可能由多种原因引起。本文将详细分析存储卡出现此类问题的各种原因&#xff0c;并提供针对性的解决方法。通过深入了解这些原因和解决方案&#xff0c;读者可以有效地应对存储卡显示0字节的故障&#xff0c;从而恢复存储卡的正…

博主自制PDF转换工具丨支持PDF转图片丨PDF转word丨PDF转Excel丨PDF文本识别丨免费使用在线下载

博主自制PDF转换工具丨支持PDF转图片丨PDF转word丨PDF转Excel丨PDF文本识别丨免费使用在线下载 点我立即下载

CSB文件上传漏洞 -->Day4(图片挂马)

22二号&#xff0c;冬至啦&#xff0c;深圳这边只有5&#xff08;尊嘟好冷啊&#xff09;&#xff0c;写这篇文章的时候都已经是凌晨一点了&#xff0c;相信大部分的人都在温暖的被窝里面了吧&#xff01;&#xff01;&#xff08;可怜的我&#xff0c;还得写writeup&#xff0…

【XML】TinyXML 详解(一):介绍

【C】郭老二博文之&#xff1a;C目录 1、简介 优点&#xff1a; TinyXML 是一个简单、小型的 C XML 解析器&#xff0c;可以轻松集成到项目中。 TinyXML 解析 XML 文档&#xff0c;并根据该文档构建可读取、修改和保存的文档对象模型 (DOM) TinyXML 是在 ZLib 许可下发布的&a…

UG凸起命令

凸起命令是拉伸命令的补充&#xff0c;可以方便的对曲面进行拉伸切除。 当端盖中几何体类型选择默认的截面平面的时候&#xff0c;相当于拉伸命令 当端盖中几何体类型选择凸起的面的时候&#xff0c;相当于拉伸其实曲线变为选择曲线在凸起面的投影曲线&#xff0c;然后基于凸起…