Linux
Linux网课学习记录
给算法爸爸上香
爱学习的图像算法工程师一枚
展开
-
深度学习炼丹师常用Linux和Docker命令
作为一名初级炼丹术士已经快半年了,记录一下工作中常用的Linux和Docker命令。原创 2022-12-23 11:40:11 · 250 阅读 · 0 评论 -
文件锁单开进程
flock.c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h> #include <stdlib.h>#define _FILE_NAME_ "/home/itheima/temp.lock"int main(){ int fd=open(_FILE_NAME_原创 2021-02-28 22:33:44 · 119 阅读 · 0 评论 -
信号量
信号量是加强版的互斥锁,允许多个线程访问共享资源int sem_init(sem_t *sem,int pshared,unsigned int value);sem 定义的信号量,传出pshared 0代表线程信号量,非0代表进程信号量value 定义信号量的个数摧毁信号量int sem_destroy(sem_t *sem);申请信号量int sem_wait(sem_t *sem); 当信号量为0时阻塞释放信号量int sem_post(sem_t *sem);sem_produ原创 2021-02-28 15:42:51 · 141 阅读 · 0 评论 -
生产者和消费者模型
条件变量:可以引起阻塞,并非锁,要和互斥量组合使用超时等待int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);struct timesec{time_t tv_sec; //秒,绝对时间,填写的时候time(NULL)+600设置超时600slong tv_nsec; //纳秒}条件变量阻原创 2021-02-28 14:34:01 · 92 阅读 · 0 评论 -
读写锁
读写锁的特点:读共享,写独占,写的优先级高读写锁仍然是一把锁,有不同的状态:未加锁,读锁,写锁线程A加写锁成功,线程B请求读锁(线程B阻塞)线程A持有读锁,线程B请求写锁(线程B阻塞)线程A持有读锁,线程B请求读锁线程A持有读锁,线程B请求写锁,线程C请求读锁(BC阻塞,A释放后B加锁,B释放后C加锁)线程A持有写锁,线程B请求读锁,线程C请求写锁(BC阻塞,A释放后C加锁,C释放后B加锁)读写锁使用场景:适合读的线程多初始化读写锁int pthread_rwlock_init(pthre原创 2021-02-28 00:13:39 · 259 阅读 · 0 评论 -
互斥量
两个线程访问同一块共享资源,如果不协调顺序,容易造成数据混乱加锁mutexpthread_mutex_init 初始化pthread_mutex_destroy 摧毁pthread_mutex_lock 加锁pthread_mutex_unlock(pthread_mutex_t *mutex) 解锁互斥量的使用步骤:初始化、加锁、执行逻辑–共享操作数据、解锁注意事项:加锁需要最小粒度,不要一直占用临界区尝试加锁pthread_mutex_trylock(pthread_mutex_t原创 2021-02-28 00:12:41 · 130 阅读 · 0 评论 -
线程同步
线程访问同一个共享资源,需要协调步骤线程同步:协调步骤,顺序执行解决同步问题:加锁数据混乱的原因:1.资源共享(独占资源则不会)2.调度随机(意味着数据访问会出现竞争)3.线程间缺乏必要的同步机制只能解决第三点pthread_print.c#include <stdio.h>#include <string.h>#include <unistd.h>#include <stdlib.h>int sum=0;void* thr1(原创 2021-02-25 21:52:54 · 109 阅读 · 0 评论 -
线程属性设置分离
pthread_var.c#include <stdio.h>#include <string.h>#include <unistd.h>#include <pthread.h>int var=100;void* thr(void *arg){ printf("I am a thread! self=%lu,var=%d\n",pthread_self(),var);//var=1003 sleep(2); var=1原创 2021-02-25 20:38:31 · 318 阅读 · 0 评论 -
线程分离
线程分离int pthread_detach(pthread_t thread);此时不需要pthread_join回收资源pthread_detach.c#include <stdio.h>#include <string.h>#include <unistd.h>#include <pthread.h>void* thr(void *arg){ printf("I am a thread! pid=%d,tid=%lu\n",g原创 2021-02-25 19:46:02 · 77 阅读 · 0 评论 -
杀死进程
pthread_cancel需要出入tid返回值:失败返回errno,成功返回0被pthread_cancel杀死的进程状态,退出状态为PTHREAD_CANCELED强行设置取消点pthread_testcancel()pthread_cancel.c#include <stdio.h>#include <unistd.h>#include <pthread.h>void* thr(void *arg){ while(1){原创 2021-02-25 19:45:22 · 166 阅读 · 0 评论 -
线程的回收
线程回收函数 -阻塞等待回收int pthread_join(pthread_t thread,void **retval)thread 创建时传出的第一个参数retval 代表传出线程的退出信息pthread_rtn.c#include <stdio.h>#include <unistd.h>#include <pthread.h>void* thr(void *arg){ printf("I am a thread! pid=%d,tid=原创 2021-02-23 22:34:20 · 372 阅读 · 0 评论 -
线程的退出
线程退出函数pthread_exit线程退出注意事项:在线程中使用pthread_exit在线程中使用return(主控线程return代表退出进程)exit代表退出整个进程pthread_exit.c#include <stdio.h>#include <unistd.h>#include <pthread.h>#include <stdlib.h>void* thr(void *arg){ printf("I am a t原创 2021-02-23 22:33:41 · 204 阅读 · 0 评论 -
线程的创建
创建一个线程int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine)(void *),void *arg);thread 线程的id,传出参数attr 代表线程的属性void *(*start_routine)(void *) 函数指针,void func(void)arg线程执行函数的参数返回值:成功返回0,失败返回errno编译的时候要加pthread库pthread_c原创 2021-02-23 22:32:48 · 139 阅读 · 1 评论 -
线程的概念
线程的概念:轻量级的进程,一个进程内部可以有多个线程,默认一个进程只有一个线程线程是最小的执行单位,进程是最小的系统资源分配单位内核实现都是通过clone函数实现的线程也有自己的PCB获得错误码对应的错误信息char *strerror(int errnum);线程的优点:提高并发性,占用资源少,通信方便线程的缺点:调试困难,库函数不稳定,对信号支持不好...原创 2021-02-23 22:31:48 · 141 阅读 · 1 评论 -
守护进程
守护进程会话:进程组的更高一级,多个进程组对应一个会话进程组:多个进程在同一个组,第一个进程默认是进程组的组长创建会话的时候,组长不可以创建,必须由组员创建创建会话的步骤:创建子进程,父进程终止,子进程成为会长守护进程的步骤:创建子进程fork父进程退出子进程当会长setsid,切换工作目录$HOMR设置掩码umask关闭文件描述符0,1,2(为了避免浪费资源)执行核心逻辑退出创建一个守护进程,每分钟在$HOME/log/下创建一个文件:程序名.时间戳daemon.c#inc原创 2021-02-23 15:48:14 · 110 阅读 · 0 评论 -
SIGCHLD回收子进程
SIGCHLD信号处理子进程在暂停或提出时发送SIGCHLD信号,可以通过捕捉该信号来回收子进程child_catch.c#include <stdio.h>#include <unistd.h>#include <sys/wait.h>#include <signal.h>void catch_sig(int num){ pid_t wpid=waitpid(-1,NULL,WNOHANG); if(wpid>0){原创 2021-02-22 22:31:46 · 210 阅读 · 0 评论 -
sigaction
信号捕捉防止进程意外死亡typedef void(*sighandler_t)(int);sighandler_t signal(int signum,sighander_t handler);signum要捕捉的信号handler要执行的捕捉函数指针,函数应该声明void func(int);注册捕捉函数int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);signum 捕捉的信号ac原创 2021-02-22 14:15:57 · 150 阅读 · 0 评论 -
信号集函数
信号集处理函数清空信号集int sigempty(sigset_t *set);填充信号集int sigfillset(sigset_t *set);添加某个信号到信号集int sigaddset(sigset_t *set,int signum);从集合中删除某个信号int sigdelset(sigset_t *set,int signum);判断信号是否为集合中的成员int sigismember(const sigset_t *set,int signum);设置阻塞或者解除阻原创 2021-02-22 13:19:25 · 123 阅读 · 0 评论 -
setitimer
setitimer周期性发送信号int setitimer(int which,const struct itimerval *new_value,struct itimerval *old_value);whichITIMER_REAL 自然定时发SIGALRMITIMER_VIRTUAL 计算进程执行时间 SIGVTALRMITIMER_PROF 进程执行时间+调度时间 ITIMER_VIRTUALnew_value 要设置的闹钟时间old_value 原闹钟时间struct itime原创 2021-02-21 21:56:51 · 192 阅读 · 0 评论 -
alarm发送信号
时钟信号alarm 定时给自己发送SIGALRMunsigned int alarm(unsigned int seconds);seconds 几秒后发送信号返回值,上次闹钟剩余的秒数特别的,如果传入参数为0,代表取消闹钟alarm.c#include <stdio.h>#include <unistd.h>int main(int argc,char * argv[]){ int ret=0; ret=alarm(6); printf原创 2021-02-21 15:43:19 · 278 阅读 · 0 评论 -
raise和abort
raise给自己发送信号int raise(int sig);raise.c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <signal.h>#include <stdlib.h>int main(int argc,char * argv[]){ printf("I will die\n"); sleep(2); /原创 2021-02-21 15:31:39 · 126 阅读 · 0 评论 -
信号的产生
系统api产生信号kill函数int kill(pid_t pid,int sig);pid大于0,代表要发送的进程IDpid=0,代表当前调用进程组内所有进程pid=-1,代表有权限发送的所有进程pid小于0,代表-pid对应组内所有进程sig 对应的信号killfather.c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>原创 2021-02-21 15:30:33 · 144 阅读 · 0 评论 -
信号
信号的概念信号的特点:简单,不能带大量信息,满足特定条件发生信号的机制:进程B发送给进程A,内核产生信号,内核处理信号的产生:按键产生 ctrl+c ctrl+z ctrl+调用函数 kill raise abort定时器 alarm setitimer命令产生 kill硬件异常 段错误,浮点型错误,总线错误,SIGPIPE信号的状态:产生 递达(信号到达并且处理完) 未决(信号被阻塞)信号的默认处理方式:忽略 执行默认动作 捕获 (9和19号信号不能捕捉,不能忽略,甚至不能阻塞 )信原创 2021-02-21 15:29:34 · 88 阅读 · 0 评论 -
mmap通信
mmap共享映射区void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);addr 传NULLlength 长度prot PROT_READ可读 PROT_WRITE可写flags MAP_SHARED共享的,修改内存会影响原文件 MAP_PRIVATE私有的fd 文件描述符,open打开一个文件offset 偏移量返回值:成功返回可用的内存首地址,失败返回MAP_FAILED释放映射区int原创 2021-02-20 21:19:02 · 282 阅读 · 0 评论 -
fifo通信
FIFO有名管道,实现无血缘关系进程通信创建一个管道的伪文件mkfifo myfifo 命令也可以用函数int mkfifo(const char *pathname,mode_t mode);内核会针对fifo文件开辟一个缓冲区,操作fifo文件,可以操作缓冲区,实现进程通信–实际上是文件读写open注意事项,打开fifo文件时,read端会阻塞等待write端打开,write端也会阻塞等待read打开man 7 fifo 查看fifo信息fifo_w.c#include <stdi原创 2021-02-19 23:06:34 · 519 阅读 · 0 评论 -
管道通信
常见的通信方式:单工(广播),半双工(对讲机),全双工(电话)管道:半双工通信管道函数:int pipe(int pipefd[2]);pipefd读写文件描述符,0代表读,1代表写返回值:失败返回-1,成功返回0pipe.c#include<stdio.h>#include<unistd.h>#include<sys/types.h>#include<sys/wait.h>int main(int argc,char *argv[])原创 2021-02-19 20:42:30 · 187 阅读 · 0 评论 -
IPC通信
IPC(Inter Process Communication)进程间通信,通过内核提供的缓冲区进行数据交换的机制。IPC通信的方式:pipe 管道–最简单fifo 有名管道mmap 文件映射IO–速度最快本地socket 最稳定信号 携带信息量最小共享内存消息队列...原创 2021-02-19 15:34:05 · 118 阅读 · 0 评论 -
wait函数和waitpid函数
子进程回收回收子进程,知道子进程的死亡原因作用:阻塞等待,回收子进程资源,查看死亡原因pid_t wait(int *status);status状态返回值:成功返回终止的子进程ID,失败返回-1子进程的死亡原因:正常死亡WIFEXITED 如果WIFEXITED为真,使用WEXITSTATUS得到退出状态非正常死亡WIFSIGNALED 如果WIFSIGNALED为真,使用WTERMSIG 得到信号wait.c#include<stdio.h>#include<un原创 2021-02-18 21:35:33 · 377 阅读 · 0 评论 -
孤儿进程与僵尸进程
孤儿进程:父进程死了,子进程被init进程领养僵尸进程:子进程死了,父进程没有回收子进程的资源(PCB)如何回收僵尸进程:杀死父亲,由init进程领养,无法回收orphan.c#include<stdio.h>#include<unistd.h>int main(){ pid_t pid=fork(); if(pid==0){ while(1){ printf("I am child,pid=%d,ppid原创 2021-02-18 12:41:09 · 77 阅读 · 0 评论 -
exec函数
exec族函数执行其他程序int execl(const char path,const char arg,…/(char)NULL*/);执行程序的时候,使用PATH环境变量,执行的程序可以不用加路径int execlp(const char file,const char arg,…/(char)NULL*/);file要执行的程序arg参数列表,最后需要一个NULL作为结尾返回值:只有失败才返回execl.c#include<stdio.h>#include<un原创 2021-02-16 20:19:32 · 130 阅读 · 0 评论 -
父子进程
进程共享父子进程相同处:全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式父子进程不同之处:进程ID、fork返回值、父进程ID,进程运行时间、定时器、未决槽信号父子进程间遵循读时共享写时复制的原则,节省内存开销父子进程不共享全局变量shared.c#include<stdio.h>#include<unistd.h>int var=100;int main(int argc,char *argv[]){原创 2021-02-16 16:36:10 · 551 阅读 · 0 评论 -
创建n个进程
nfork.c 创建5个子进程#include<stdio.h>#include<unistd.h>#include<stdlib.h>int main(){ int n=5; int i=0; for(i=0;i<5;i++){ pid=fork(); if(pid==0){ //son printf("I am child,pid=%d,ppi原创 2021-02-16 13:49:05 · 260 阅读 · 0 评论 -
进程控制
创建一个新的进程pip_t fork(void);返回值:失败返回-1;成功有两次返回,父进程返回子进程的id,子进程返回0获得pid,进程id,获得当前进程pip_d getpid(void);获得当前进程父进程的idpip_d getppid(void);fork.c#include<stdio.h>#include<unistd.h>#include<stdlib.h>int main(){ printf("Begin ....\n原创 2021-02-15 20:57:03 · 103 阅读 · 1 评论 -
获取环境变量
环境变量:env写法:key=val获取环境变量:char *getenv(const char *name);getenv.c#include<stdio.h>#include<stdlib.h>int main(){ printf("homepath is [%s]\n",getenv("HOME")); return 0;}配置环境变量.bashrcexport key=cal...原创 2021-02-15 17:27:20 · 166 阅读 · 0 评论 -
进程的概念
什么是程序?编译好的二进制文件。什么是进程?运行着的程序。程序员的角度:运行一系列指令的过程操作系统角度:分配系统资源的基本单位区别:程序占用磁盘,不占用系统资源内存占用系统资源一个程序对应多个进程,一个进程对应一个程序程序没有生命周期,进程有生命周期进程的状态:就绪 运行 挂起 终止MMU作用:虚拟内存和物理内存的映射修改内存访问级别用户空间映射到物理内存是独立的...原创 2021-02-15 17:26:34 · 244 阅读 · 0 评论 -
dup2和dup
dup2重定向int dup2(int oldfd,int newfd);关闭newfd对应的文件描述符,将newfd重新指向为oldfd对应的文件dup复制文件描述符int dup(int oldfd);新返回一个文件描述符指向oldfd对应的文件实现:在代码中执行两次printf(“hello world\n”);一次输出到hello文件,一次输出到屏幕涉及到文件重定向dupdu.c#include<stdio.h>#include<unistd.h>#i原创 2021-02-14 22:36:35 · 126 阅读 · 0 评论 -
读目录相关函数
统计指定目录下普通文件的个数,要求递归子目录$find ./ -type f |wc -l打开目录DIR *opendir(const char name);name打开的目录返回值 返回DIR的指针,指向目录项的信息读目录struct dirent *readdir(DIR *dirp);dirp传入参数,opendir返回的指针返回值:NULL代表读到末尾或者有错误读到目录项的内容关闭目录int closedir(DIR *dirp)dirp opendir得到的DIR指针原创 2021-02-14 22:25:49 · 193 阅读 · 0 评论 -
mkdir
创建目录int mkdir(const char *pathname,mode_t mode);pathname路径mode mode & ~umask & 0777 注意权限,如果目录没有可执行权限不可进入mkdir.c#include<stdio.h>#include<sys/type.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>int原创 2021-02-14 22:24:53 · 116 阅读 · 0 评论 -
chdir_getcwd
获得当前工作路径char *getcwd(char *buf,size_t size);buf传出参数,路径size缓冲区大小返回值:成功返回路径的指针,失败返回NULL改变工作路径(进程独有)int chdir(const char *path)path对应的工作路径返回值:成功返回0,失败返回-1cwd_chdir.c#include<stdio.h>#include<unistd.h>#include<sys/types.h>#includ原创 2021-02-14 22:24:10 · 142 阅读 · 0 评论 -
chown_rename
改变用户和组int chown(const char *pathname,uid_t owner ,gid_t group);pathname文件名owner用户ID,/etc/passwdgroup 组ID,/etc/group重命名文件int rename(const char *oldpath,const char *newpath)oldpath旧文件newpath新文件rename.c#include<stdio.h>int main(){ //ren原创 2021-02-14 22:23:17 · 78 阅读 · 0 评论