Linux常用命令和函数

查看进程信息命令:ps aux

查看环境变量命令:env

pid_t fork(void) 调用一次创建一个进程,在父进程中返回子进程的pid,在子进程中返回0

getpid() 返回调用进程的pid

execl进程重载:execl(const char* path,argv[0],argv[1],....,"NULL");

        path:你要重载的程序/命令的路径

        argv: 程序/命令的参数 例如:ps aux ----> execl("/bin/ps","ps",argv[1],"aux","NULL");

        NULL:最后一个参数一定要传NULL表示传参结束,不写函数失败。

pid_t zpid = wait(NULL(有一个int*类型的status传出参数用于获取子进程退出信息用于验尸));

pid_t zpid = waitpid(pid_t pid,int* status,int opt);

参数:

pid:指定回收的方式

        >0:指定一个子进程pid,回收这个子进程

        -1:回收任意子进程

        =0:同组回收,只能回收掉与父进程同组的所有子进程

         <0(组id gpid):指定组id,实现夸组回收

status:暂时传NULL,用于验尸,传出参数,里面是子进程的退出信息        

opt:工作模式

        WNOHANG:非阻塞关键字,可以让waitpid进行非阻塞回收,非阻塞回收可以让父进             程在回收过程中穿插执行自身的工作,非阻塞回收也是经典的主动回收方式。

返回值:

        三种返回值 >0:表示回收成功,-1:表示回收失败,0:表示非阻塞返回

进程的退出和status参数,验尸

WIFEXITED(status): 判断进程是否是正常退出

WEXITSTATUS(status):返回的是退出码或返回值

WIFSIGNALED(status):判断进程是否是正常退出

WTERMSIG(status): 获取杀死子进程的信号编号

匿名管道:pipe(fds)        int fds[2]:fds[0]读端, fds[1]写端

创建有名管道文件命令:mkfifo 管道名

文件共享映射mmap

头文件:#include<sys/mman.h>

void* ptr = mmap(NULL(映射内存地址传) , 映射大小 , 映射内存权限 , 映射方式 , 文件描述符 , 0(映射偏移量))

返回值:成功返回映射内存地址,失败返回MAP_FAILED关键字

参数1: 映射内存地址,传NULL让系统自行分配映射内存,也可以malloc自己分配

参数2: 映射大小,一般是文件大小

参数3: 映射内存权限,一般是PROT_READ|PROT_WRITE|PROT_EXEC|PROT_NONE

参数4: 映射方式,有私有映射MAP_PRIVATE,共享映射MAP_SHARED

私有映射:把映射文件内容拷贝到映射内存,称之为拷贝映射,一方改变对另一方没有影响

共享映射:建立了一种sync同步机制,将文件数据映射给进程,一方改变会同步给另一方

参数5: 映射文件的描述符,映射时使用访问磁盘数据

参数6: 映射偏移量,mmap支持偏移映射,也就是一次映射文件一部分,用来处理大文件

munmap(void* ptr,映射大小)         释放映射内存

ftruncate(fd , 扩展大小)                 扩展文件大小

getpgrp()                                       返回进程组id

setpgid(pid_t pid , pid_t gid)         创建新组/组员转移

getsid(pid_t pid)                            获取会话id

setsid()                                          创建新会话

ps ajx                                            查看进程间关系

kill( 1000 , 0 )                                可以检查1000这个进程是否存活

kill(-1000 , 9)                                 杀死1000这个组里的进程

kill -l                                               获取信号列表

信号头文件:#include<signal.h>

组合键:

ctl+c(SIGINT=2,杀死进程)

ctl+\(SIGQUIT=3,杀死进程)

ctl+z(SIGTSTP=20,挂起进程)

命令:

kill - signo pid 向任意进程发送任意信号

函数:

kill(pid_t pid,int signo)  向任意进程发送任意信号

raise(int signo)              向调用进程发送任意信号,谁调给谁发

abort(void)                     向调用进程发送SIGABRT信号

unsigned int alarm(unsigned int 秒数)        定时到时系统发送SIGALARM信号

信号行为结构体

struct sigaction act;

        act.sa_handler类型:void(*act.handler)(int)

        信号行为选择

        act.sa_handler = SIG_DFL(默认) | SIG_IGN(忽略) | sigdo(捕捉函数地址)

        选项

        act.sa_flags = 0; 默认选0

        临时屏蔽字

        act.sa_mask 不使用但是要初始化

        sigemptyset(&act.sa_mask);        初始化临时屏蔽字

捕捉函数的接口还有,两个,其中sa_restorer没有参数属于比较老的不怎么用了,sa_sigaction是有三个参数,可以用来进程间通信,使用这个接口函数注意sa_flags要设置成SA_SIGINFO

sa_sigaction(int n, siginfo_t* info, void* arg)

进程传递的数据被保存在info结构体中

整形被保存在info->si_int

地址数据被保存在info->si_ptr。

sigaction(SIGINT,&newact,&oldact);

sigaction(SIGINT(对那个信号操作),&act(新的信号行为结构体),&oact(传出参数,传出旧的信号行为结构体,不要就传NULL))

通过屏蔽字屏蔽信号可以实现让信号临时失效,但是信号并没有消失卡在那里,只要解除屏蔽,立即处置进程

信号集的类型 sigset_t set

初始化信号集所有位为0 sigemptyset(&set)

初始化信号集所有位为1 sigfillset(&set)

将特定信号的位码置为1 sigaddset(&set,信号宏名或信号编号)

将特定信号的位码置为0 sigdelset(&set,信号宏名或信号编号)

查看特定信号的位码置是0是1并返回 int code = sigisnumber(&set,信号宏名或信号编号)

采用替换方式更改屏蔽字

SETMASK直接覆盖

sigprocmask(SIG_SETMASK,&newset,&oldset(传出以前的信号集就传,不要就传NULL))

sigpending(sigset_t* pset) 调用函数后,系统将进程的未决信集传出到pset

pause() 执行立即挂起,当察觉到一个信号就唤醒,任意信号都能唤醒,能察觉的信号必须已递达并有处理动作

sigsuspend(sigset_t*) 挂起的同时设置临时屏蔽字

sigqueue(pid_t pid, int signo, union sigval val)  发送信号的同时发送数据

union sigval         

        sigqueue 用来传递数据用的联合体参数

        联合体 union sigval val 有两个成员,一个传整形数据,一个传地址数据

        val.sival_int (int)

        val.sival_ptr (void*)

ps -eLf         查看系统中所有线程

ps -Lf pid     查看某一个进程的所有线程

pid                  进程id

LWP               轻量级进程编号(不是tid , 而是调度编号)

NLWP            轻量级进程数量

pthread_t tid  用于存储线程id

返回调用线程tid:pthread_self()

线程创建函数 pthread_create

int err = pthread_create(pthread_t* tid , pthread_attr_t* attr , void* (*tjob)(void*arg),void* arg)

返回值:

        线程创建函数,成功返回0,失败返回整形错误号需要用户自行接收,而后使用strerror进行错误处理

参数:

        tid : 线程创建成功, 将此线程的id,传出到变量中

        attr: 线程属性参数, 传出NULL表示使用默认属性

        tjob : 线程工作地址, 此参数为函数指针void* (*tjob)(void*arg)

        arg : 线程函数参数, 系统创建线程后调用twk而后把arg传入twk中

pthread_join(pthread_t tid , void** reval)线程回收函数

返回值:

成功返回0,失败返回错误码

参数:

        tid :要等待结束的线程的标识符。

        retval:用于存储线程返回值的指针。如果该线程没有返回值,则该参数可以设置为NULL。

线程回收,接受线程返回值,如果不回收会引发僵尸线程(TCB)残留,默认情况下,线程均是回收态线程(PTHREAD_JOINABLE),这类线程退出后,需要进行join回收操作,否则导致内存泄露引发僵尸线程(TCB)残留。

阻塞函数,线程未退出等待,退出后立即回收,调用pthread_join函数会阻塞当前线程,直到指定的线程结束为止。

pthread_exit((void *)9)        线程退出函数

线程退出并返回特定值,无论那种线程使用,都只结束当前线程与进程无关。

pthread_cancel(pthread_t tid)        线程取消函数

线程取消,参数为目标线程的tid,可以将目标线程杀死。

如果需要对线程的返回值进行验证,需要使用回收线程,否则分离线程即可。

如果线程取消,那么回收线程得到的返回值为-1,线程开发时不允许使用-1作为返回值,保留给cancel,这样回收线程时可以判断线程是正常return还是被其他线程cancel取消杀死。

信号是100%会其作用,cancel不是,cancel需要有系统调用才会处理。

pthread_testcancel()        触发一次系统调用

调用后触发一次系统调用以解决cancel后线程无法杀死的情况,配合cancel使用

pthread_detach(pthread_t tid);线程分离设置

可以讲一个线程设置为分离态。

默认线程退出状态为回收态,但是可以变为分离态,分离态线程结束后系统自动回收线程资源。

将自己设置为分离态:pthread_detach(pthread_self());

线程属性结构体 pthread_attr_t attr

int err = pthread_create(pthread_t tid , pthread_attr_t* attr , void* (*twk)(void*arg),void* arg)

pthread_create第二个参数要的就是这个结构体的地址,传NULL表示使用默认结构体,默认属性

用户可以自定义线程属性结构体,而后创建线程,决定线程形态

线程属性结构体成员有:

线程优先级指针 默认=dfl

线程警戒缓冲区大小 默认=4096Byte 防止栈溢出机制,溢出会污染进程用户空间

线程退出状态 默认=PTHREAD_JOINABLE

线程栈地址 默认=null

线程栈大小 默认=0

int err = pthread_create(pthread_t tid , pthread_attr_t* attr , void* (*twk)(void*arg),void* arg)

自定义线程属性变量

pthread_attr_t newattr;

初始化线程属性

pthread_attr_init(&newattr); 初始化线程属性,初始完毕为默认属性

销毁释放属性

pthread_attr_destroy(&newattr); 使用完释放属性

获取属性中的退出状态

pthread_attr_getdetachstate(&newattr,int* detachstate); 传出属性中的退出状态到变量detachstate中

设置属性中的退出状态

pthread_attr_setdetachstate(&newattr,PTHREAD_CREATE_DETACHED / PTHREAD_CREATE_JOINABLE); 向属性中设置状态

获取线程属性中的栈信息

pthread_attr_getstack(&newattr, void ** stackaddr, size t*stacksize); 参数是传出参数,获取属性中的栈地址与大小,并传出

设置线程属性的栈信息

pthread_attr_setstack(&newattr, void * stackaddr, size t stacksize); 设置属性中的栈地址与大小

互斥锁类型

pthread_mutex_t lock;

动态初始化互斥锁

pthread_mutex_init(&lock,NULL);

释放锁内存

动态初始化对应的销毁

pthread_mutex_destroy(&lock);

静态初始化互斥锁

lock = PTHREAD_MUTEX_INITIALIZER;

不需要释放

阻塞上锁

pthread_mutex_lock(&lock);

解锁

pthread_mutex_unlock(&lock);

非阻塞上锁

支持非阻塞上锁,如果获取不到锁,无需阻塞等待,函数立即返回

pthread_mutex_trylock(&lock);

互斥锁属性变量

pthread_mutexattr_t attr;

初始化属性

初始化后的锁属性为线程互斥

pthread_mutexattr_init(&attr);

设置互斥锁属性为进程锁

pthread_mutexattr_setpshared(&attr,PTHREAD_PROCESS_SHARED);

PTHREAD_PROCESS_SHARED 进程锁

PTHREAD_PROCESS_PRIVATE 线程锁

初始化时使用自定义锁属性

初始化互斥锁时,加上属性

pthread_mutex_init(&lock,&attr);

静态初始化的互斥锁必然是线程锁,想要使用进程锁必须动态初始化

释放锁属性

pthread_mutexattr_destroy(&attr);

读写锁类型

pthread_rwlock_t lock;

动态初始化读写锁

pthread_rwlock_init(&lock,NULL);

释放锁内存

动态初始化对应的销毁

pthread_rwlock_destroy(&lock);

静态初始化读写锁

lock = PTHREAD_RWLOCK_INITIALIZER;

阻塞上读锁

pthread_rwlock_rdlock(&lock);

阻塞上写锁

pthread_rwlock_wrlock(&lock);

解锁

两个锁都能解除

pthread_rwlock_unlock(&lock);

条件变量类型

pthread_cond_t cd

挂起线程在其中,也可以唤醒这些线程(线程的挂起/唤醒点)

初始化条件变量

静态初始化

cd = PTHREAD_COND_INITIALIZER;

动态初始化

pthread_cond_init(&cd,NULL);

销毁条件变量

pthread_cond_destroy(&cd);

挂起到条件变量

pthread_cond_wait(&cd,&lock);

参数1:条件变量地址,参数2:要操作的锁的地址

谁调谁挂起,线程调用函数后将线程挂起在指定条件变量中挂起的同时解锁

此函数有两次执行,第一次是挂起并解锁,第二次被唤醒时继续执行wait自动再上锁

将条件变量中挂起的线程唤醒一个

pthread_cond_signal(&cd);

唤醒条件变量中所有挂起的线程

pthread_cond_broadcast(&cd);

死锁产生的四个必要条件

1.保持与请求 (占用资源的情况下还有申请新资源)

2.互斥条件 (请求占用的资源,会产生阻塞挂起)

3.不可剥夺条件 (占用资源的线程只要不主动释放,其他人无法剥夺资源)

4.循环等待条件 (每个单元都在等待相邻单元的资源)

select(maxfd+1,&set,NULL,NULL,struct timeval* tim);

参数一

        监听文件描述符数量,从0开始 可以写maxfd(变量)+1即可覆盖所有的文件描述符 如上图serfd为3但一共有四个文件描述符所以+1

参数二三四

        要监听的事件,分别为 ,,异常,&set为fd_set类型

        全监听则为 select(maxfd+1,&set,&set,&set,NULL);

        只监听读 select(maxfd+1,&set,NULL,NULL,NULL);

最后一个参数

        struct timeval* tim结构体指针,tim参数表示select工作模式

        传NULL表示阻塞监听

        struct timeval* tim; tim->second = 0; tim->us = 0; 这样为非阻塞监听

        struct timeval* tim; tim->second = 20; tim->us = 0; 这样为定时阻塞监听,比如传20就是阻塞20秒就返回

返回值

        ready就绪数量(int),返回就绪数量,不返回是谁就绪

fd_set set;        监听集合类型大小1024

FD_ZERO(&set);                  初始化为0

FD_SET(int sockfd,&set);    设置监听,将某一个Socket的位置为1

FD_CLR(int sockfd,&set);    取消监听,将某一个Socket的位置为0

FD_ISSET(int sockfd,&set); 返回集合中对应位置的监听位码,遍历Socket数组判断哪个Socket就绪时可用

struct pollfd类型

监听集合为结构体数组

struct pollfd listen_array[1000];

成员:

listen_array[0].fd = sockfd; 监听的 socket 设置 socket表示监听,设置-1表示取消监听

listen_array[0].events = POLLIN|POLLOUT|POLLERR; 设置监听什么类型的事件

listen_array[0].revents  如果就绪传出就绪事件,例如写就绪则 = POLLIN

int ready = poll( listen_array , array_size , int timeout);

参数1: 监听数组的首地址

参数2: 最大监听数---监听数组的大小

参数3: -1阻塞模式工作 0非阻塞模式工作 >0定时阻塞单位是毫秒传几就是几毫秒

处理完就绪将对应socket在数组中的revents归0        listenarray[i].revents = 0;

返回值:就绪数量

 

节点类型:  struct epoll_event

struct epoll_event node;

成员:

node.data.fd = sock; 监听的Socket

node.events = EPOLLIN|EPOLLOUT|EPOLLERR 监听的事件

还有一个隐藏的callback()回调函数

监听树

监听集合使用红黑树

创建监听树

int epfd = epoll_create(int size);

参数:int size

创建监听树的大小

返回值:int epfd

监听树的文件描述符

操纵监听树(添加,删除,修改)epoll_ctl

epoll_ctl( epfd,cmd ,int socketfd,&node);

参数1:

        操作的监听树

参数2:

操作模式

        EPOLL_CTL_ADD添加节点

        EPOLL_CTL_DEL删除节点

        EPOLL_CTL_MOD修改节点 只能修改监听事件无法修改socket本身(会导致Socket与索引不一致)

参数3:

        socket,与节点中的一致,也是节点的索引编号

参数4:

        节点的地址

返回值:

        成功:返回0

        失败:返回-1

监听函数epoll_wait,阻塞监听socket事件

epoll_wait(epfd , struct epoll_event* array , int size , -1);

参数1:

        监听树的文件描述符,表示对哪个树进行监听

参数2:

        就绪队列,是节点结构体的数组 struct epoll_event*

参数3:

        最大就绪数,一般和最大监听数相等

        如果最大监听数为1000,最大就绪数为500表示对1000个sock监听但最多只会让500个socket就绪

参数4:

        -1表示阻塞监听

返回值:

        小于0:出错 等于0:超时 大于0:返回就绪事件个数

边缘模式关键字 EPOLLET

默认情况下是水平模式,要想使用边缘模式监听需要添加节点的时候加关键字EPOLLET

node.data.fd = sock;

node.events = EPOLLIN|EPOLLET;

pthread_kill(tid,0)  返回ESRCH表示线程已死返回0否则存活返回1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值