网站建设资讯

NEWS

网站建设资讯

linux执行命令不堵塞 linux命令卡住 无法退出

linux有哪些信号不会被阻塞

1. 信号在内核中的表示

创新互联建站成都网站建设按需定制设计,是成都网站营销推广公司,为成都软装设计提供网站建设服务,有成熟的网站定制合作流程,提供网站定制设计服务:原型图制作、网站创意设计、前端HTML5制作、后台程序开发等。成都网站建设热线:13518219792

我们知道了信号产生的各种原因,而实际执行信号处理的动作,叫做信号递达(Delivery)。信号从产生到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞(Block)某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。

注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

每个信号都有两个标志位分别表示阻塞和未决,,还有一个函数指针表示处理动作,信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。

SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。

SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。

SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。

如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?

POSIX.1允许系统递送该信号一次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。

从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信

号集中“有效”和“无效”的含义是该信号是否处于未决状态。

2. 信号集操作函数

sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统实现,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset_t变量,而不应该对它的内部数据做任何解释,比如用printf直接打印sigset_t变量是没有意义的。

#include signal.h

int sigemptyset(sigset_t *set); ----- 初始化set指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号.

int sigfillset(sigset_t *set); ---- 初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号。

int sigaddset(sigset_t *set, int signo);

int sigdelset(sigset_t *set, int signo);

int sigismember(const sigset_t *set, int signo);

注意,在使用sigset_t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号集处于确定的状态。

3. sigprocmask

调用函数sigprocmask可以读取或更改进程的信号屏蔽字。

如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。如果oset和set都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。假设当前的信号屏蔽字为mask,下表说明了how参数的可选值。

Linux 怎样实现非阻塞connect

1. 设置socket

int oldOption = fcntl(sockfd, F_GETFL);

int newOption = oldOption | O_NONBLOCK;

//设置sockfd非阻塞

fcntl(sockfd, F_SETFL, newOption);12345

2. 执行connect

如果返回0,表示连接成功,这种情况一般在本机上连接时会出现(否则怎么可能那么快)

否则,查看error是否等于EINPROGRESS(表明正在进行连接中),如果不等于,则连接失败

int ret = connect(sockfd, (struct sockaddr*)addr, sizeof(addr));

if(ret == 0)

{

//连接成功

fcntl(sockfd, F_SETFL, oldOption);

return sockfd;

}

else if(errno != EINPROGRESS)

{

//连接没有立即返回,此时errno若不是EINPROGRESS,表明错误

perror("connect error != EINPROGRESS");

return -1;

}12345678910111213141516

3. 使用select,如果没用过select可以去看看

用select对socket的读写进行监听

那么监听结果有四种可能

1. 可写(当连接成功后,sockfd就会处于可写状态,此时表示连接成功)

2. 可读可写(在出错后,sockfd会处于可读可写状态,但有一种特殊情况见第三条)

3. 可读可写(我们可以想象,在我们connect执行完到select开始监听的这段时间内,

如果连接已经成功,并且服务端发送了数据,那么此时sockfd就是可读可写的,

因此我们需要对这种情况特殊判断)

说白了,在可读可写时,我们需要甄别此时是否已经连接成功,我们采用这种方案:

再次执行connect,然后查看error是否等于EISCONN(表示已经连接到该套接字)。

4. 错误

if(FD_ISSET(sockfd, writeFds))

{

//可读可写有两种可能,一是连接错误,二是在连接后服务端已有数据传来

if(FD_ISSET(sockfd, readFds))

{

if(connect(sockfd, (struct sockaddr*)addr, sizeof(addr)) != 0)

{

int error=0;

socklen_t length = sizeof(errno);

//调用getsockopt来获取并清除sockfd上的错误.

if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, error, length) 0)

{

printf("get socket option failed\n");

close(sockfd);

return -1;

}

if(error != EISCONN)

{

perror("connect error != EISCONN");

close(sockfd);

return -1;

}

}

}

//此时已排除所有错误可能,表明连接成功

fcntl(sockfd, F_SETFL, oldOption);

return sockfd;

}12345678910111213141516171819202122232425262728293031323334353637383940

4. 恢复socket

因为我们只是需要将连接操作变为非阻塞,并不包括读写等,所以我们吃醋要将socket重新设置。

fcntl(sockfd, F_SETFL, oldOption);关于Linux命令的介绍,看看《linux就该这么学》,具体关于这一章地址3w(dot)linuxprobe/chapter-02(dot)html

linux read怎么设置不阻塞

不知题主的read是指socket的read还是文件的read。 默认情况下,socket的read是阻塞的; 对文件进行read,要看内核态的read接口是注册为同步接口还是异步接口(可参见file_operations结构体)

linux C 从一个管道里读数据,但是不想被阻塞,这个管道的数据时有时无,求破!

创建管道的接口除了pipe以外,Linux还支持新接口pipe2(int pipefd[2], int flags);

flags 如果传入O_NONBLOCK,读写管道时就不会阻塞了。

具体的你man 一下就知道

linux系统c语言进程不想被sleep阻塞等待怎么解决?

1、启动后台子任务,在执行命令后加操作符,表示将命令放在子shell中异步执行。可以达到多线程效果。如下,sleep10#等待10秒,再继续下一操作sleep10当前shell不等待,后台子shell等待。

2、wait命令wait是用来阻塞当前进程的执行,直至指定的子进程执行结束后,才继续执行。使用wait可以在bash脚本“多进程”执行模式下,起到一些特殊控制的作用。


新闻名称:linux执行命令不堵塞 linux命令卡住 无法退出
URL地址:http://njwzjz.com/article/dochcpp.html