Cppppp

  • 在QT中,尽量在构造的时候就指定parent对象,并且大胆的在堆上创建
  • QT中,include<QDebug> ,然后用qDebug()代替C的cout来输出
  • 比如button设置了Widget为父对象后,父对象析构时,会先自动析构子对象
  • F4,.h .cpp之间切换
  • 信号函数没有参数,槽函数也不能有参数,反之,信号函数有参数,槽函数可以没有参数
  • 信号函数和槽函数的返回值为void
  • 信号函数只需要声明,不用去实现,内部已经帮你实现了
  • 无用

Shell: 

  • chmod +x exam.sh和chmodo 777 exam.sh一样
  • unset NUM 清除NUM变量
  • 给变量赋值时,等号两边不能有空格
  • read str ;从键盘读取赋值给str,readonly num=100读取赋值给num且不能改变值
  • env  查看把有环境变量
  • 通过终端定义的环境变量是临时的,想要永久的,要在上图的两个文件中定义,而且要想立即生效,可以source ~/.bashrc
  • $?用于检查上一个命令是否正确执行,在linux中,执行正确的会返回0,执行错误的刚返回非0
  • $$是当前进程号,最常用的地方就是用于临时文件的命名,以保证名称不重复
  • shell脚本中,echo "\$3=$3",这里\是转义
  • “$NUM”这个是取值,'$NUM'这个只是简单的字符串,
  • echo "today is `date`" 这里的``就是代表执行这里面的命令,跟$(date)一样,如果是echo 'today is `date`'则是date只是整个字符串中的一员,也就是单引号里的内容全部都被当成是字符串了
  • (a=100)这个执行后不会影响到当前shell的变量值,{a=99}这个执行后会影响当前shell变量的值
  • 任何一个文件目录中都会包含.和..这两个文件
  • SHELL中else if,要写成elif,跟if一样,也要加上then
  • Case 语句中,如果用exit 1则会结束程序,如果是 N*),这个代表只要是N开关就行,
  • 上图是shell中for的另外一种格式
  • 上图的例子,比如for循环中,sum=sum+i,就要在for外面定义declare -i sum
  • mkfifio 这个是创建管道文件
  • while [ condition ]  do done 跟for循环格式很像,把while换成until,就成until语句,意义跟while相反
  • berak  continue
  • shell函数格式一:name(){ 命令集 },格式二:function name(){ 命令集 }
  • 调用有参函数时,name pram1 pram 2
  • A=10 B=20 SUM=$A+$B echo "$SUM"这个只会输出10+20,而不是30,这里要用SUM=`expr $A + $B`,注意+两边的空格不可少,不然计算不对
  • 上图是某个函数有return的时候
  • 系统调用

  • 文件IO为0,1,2,对应的标准IO为stdin,stdout,stderr
  • man man 可以查询到几个查询编号,比如man 2 open是查询系统调用open函数
  • perror("fail to open"),这个函数可以直接打印出错误码的内容
  • 上图的路径是错误码的路径
  • 系统函数close(int fd ) 头文件<unistd.h>
  • #if 1  代码内容  #endif 这个可以用于多行注释,当你要注释,就把1改成0
  • 注意,read()读到末尾时,会返回0 ,write和read返回类型为ssize_t,所以while时用!=0,而不是-1
  • remove("file.txt"),成功返回0

 进程:

  • linux中,/usr/src/存入的是系统内核
  • ps ajx查看所有进程
  • getpid(),getppid(),getpgid(getpid()),分别是获取当前进程ID父进程ID和组进程ID
  • 上图中代码会输出两次Hello,父子进程各输出一次,所以要区分好父子进程,pid_t pd;然后把父进程代码写到if(pd>0)区域,子进程代码写到if(pd=0)区域,
  • 父子进程操作同一个文件时,指针偏移量是共享的,也就是父进程读取到哪个位置,子进程轮到时也会从那个位置开始读取
  • 如果父进程先执行完,会打印出一行那啥,而后子进程执行完是不会打印那啥的,要回车一下
  • wait(), waitpid()这两个函数包含头文件<sys/wait.h><sys/types.h>
  • 子进程可以通过exit 或者_exit函数来发送退出状态,比如在子进程中exit(2),相当于status=2,然后在父进程中执行上图代码,结果是子进程执行完后,发送退出状态值2,然后父进程才执行
  • 看起来好像wait()函数是父进程等待子进程
  • wait(status)<=>wait(-1,status,0)这两个是等价的
  • exit(2)为库函数,会刷新缓冲区,_exit(2)为系统调用,不会刷新缓冲区
  • int atexit(void (*func)(void)) ;这个函数在当前进程结束时才会执行,参数是函数指针,定义函数指针对应的函数时,类型要一样,比如void fun(void),括号里的void不能少,而且它的执行顺序和注册时顺序相反
  • 使用vfork()创建子进程时,会等到子进程执行完且执行了exec()或者exit()函数后才会执行父进程,而且在子进程执行exec()或者exit()之前,父子进程共享同一块空间
  • 当exec函数执行完毕后,当前进程就结束了,原进程中的代码将不会再执行
  • 查看命令的路径,whereis命令或者which命令
  • 不带p的,要用绝对路径,但是如果是可执行文件,不带p的也可以是相对路径,
  • 信号

  • 命令kill-l 也可以查看信号对应的编号
  • 在子进程中执行代码,kill(getppid(),SIGINT),就可以让父进程退出
  • kill做为命令时,kill -2 -3194,-2是信号编号值,-3194是要终止的进程号
  • 上图第一个sec输出0,第二个sec输出2
  • raise(SIGINT)<=>kill(getpid(),SIGINT),这两个是一样的功能,给当前进程发送信号
  • abort();执行这个函数,会结束当前进程,
  • pause();当前进程挂起,直到收到别的进程发的信号,比如别的进程用kill()发信号过来
  • signal(SIGINT,SIG_DFL),signal(SIGINT,SIG_IGN)两个signal函数,前者在ctl+C后,会退出程序,后者则是忽略不予处理
  • 上图代码在main函数中循环输出Hello,第一次按ctrl+C,执行nihao beijing等,第一次按ctrl+C,则会退出程序,因为signal函数返回的是上次处理信号的函数地址,而这里上次处理信号函数就是默认处理方式
  • int sigemptyset(sigset_t *set),初始化set所指向的信号集,即清空其中所有的信号
  • int sigfillset(sigset_t *set),设置为所有信号的集合,
  • int sigismember(const sigset_t *set,int sig_num)查询sig_num是否在set集合中,在返回1,不在返回0
  • int sigaddset(sigset_t *set,int sig_num),int sigdelset(sigset_t *set,int sig_num),
  • 上图set是一个sigset_t信号集,SIGINT加入了它,然后set加入阻塞集,代码执行到3秒时按ctrl+C,由于SIGINT阻塞,所有等到5秒后,它从阻塞集中删除后,立马生效,程序退出,不会执行后面代码,如果在5秒之后才按ctrl+C,则是程序马上退出
  • Pipe 无名管道

  • 如果管道中有数据,再次写入时,会追加数据,而不会覆盖,在读数据时,会从上次读的指针位置继续读,而如果读到末尾了,则会阻塞等待
  • fgets(buf ,12,stdin),它会把'\n'也读进去
  • 要在fork()父子进程之前创建无名管道
  • 无名管道只能在有亲缘关系的进程间进行通信,比如父子进程
  • 如果在无名管道一直执行写操作且不进行读操作的话,那么管道的缓冲区将会被写满,后写操作也就会阻塞,默认无名管道缓冲区的大小为64K字节
  • int pipefd[2]; pipe(pipefd); 这个无名管道,如果close(pipefd[1])或者close(pipefd[1])就是关闭写通道或者读通道,
  • (只有读通道存在)如果管道里一开始数据了,read函数第一次读完后,第二次进去读没数据了,它不会阻塞,直接返回0
  • (读写通道都存在)如果管道里一开始数据了,read函数第一次读完后,第二次进去读没数据了,则会阻塞, fcntl(pipefd[0],F_SETFL,O_NONBLOCK)这个函数可以让read不阻塞
  • 设置为阻塞:fcntl(fd,F_SETFL,0),设置为非阻塞:  fcntl(fd,F_SETFL,O_NONBLOCK)
  • 在linuxt中,>代表内容重定向到文件中,比如ls > text.txt
  • int dup(int oldfd), int dup(int oldfd,int newfd )文件描述符的复制,比如int d=dup(1),结果d这个文件描述符功能和文件描述符1的功能一样,这个返回的d值是可用的最小的文件描述符
  • close(1);int d=dup(file_fd);这时候printf会打印到文件里,因为printf默认就是输出到文件描述符为1,此时把file的文件描述符改成1了,printf就会重定向输出到文件中,如果直接有int d=dup2(file_fd,1),功能和前者一样,它会先close(1);然后执行复制,结果就是1=dup2(file_d)
  • 如果恢复printf输出到终端,那么可以最开始的时候,int fd2=dup(1);后面在close(1);int fd3=dup(fd2),如果是用dup2,那么刚开始dup2(1,fd1);后面在dup2(fd1,1)
  • 注意,dup2(para1,para2),这个函数第二个参数如果是变量,必须初始化,不然可会被赋值为0,那么使用scanf的时候就会出问题
  • FIFO,命名管道,有名管道

  • FIFO,有名管道,它在文件系统中作为一个特殊文件而存在(不像无名管道只是存在于内存中),但是它的内容是储存于内存中,使用FIFO的进程退出后,FIFO仍然保存于文件系统中,,所以没有亲缘关系的进程可以进行通信
  • 创建FIFO文件,一:shell命令,mkfifo;二 :int mkfifo(const char* pathname,mode_t mode)
  • 第二种创建方式参数mode,就是权限的二进制数,比如0664,成功返回0,失败返回-1
  • printf("errno=%d\n",errno);可以打印出当前错误码
  • 不能使用iseek来修改有名管道的偏移量
  • 有名管道文件可以通过open函数来获得文件描述符
  • 创建两个有名管道,两个C文件,send文件负责FIFO1有读和FIFO2的写,rec文件负责FIFO1有写和FIFO2的读
  • 有名管道如果在open时候,参数是O_RDWR,就代表读写端都存在
  • 有名管道如果在open时候,参数是O_RDONLY,也就是只有读端,那么后面会在open这个位置阻塞,而不是像无名管道那样只有读口时,read没数据会直接返回0
  • 如果在open时候,参数是O_WRONLY,也会在open这个位置阻塞
  • 但是,两个C文件,一个open时候,参数是O_RDONLY,另一个open时候,参数是O_WRONLY,它俩同时操作一个FIFO文件,那么两个都不会在open位置阻塞,程序会正常执行完
  • fd=open("myfifo",O_RDONLY|O_NONBLOCK),这个就是在open fifo文件时,让open函数不会阻塞,read也不会阻塞
  • 消息队列

  • ipcs命令可以查看所有已创建的IPC对象,-q查看消息队列,-m查看共享内存,-s
  • ipcrm -q msqid删除标号为msqid的消息队列
  • int msgget(key_t key,int msgflg) 创建消息队列
  • system("ipcs -q") 这个函数里的参数就是shell命令
  • 如果第二个参数是IPC_RMID,第三个参数可以直接传NULL
  • 共享内存

  • int shmget(key_t key,size_t size,int shmflg) 创建共享内存,shmflag和msgflg一样
  • 上图是共享内存的映射(attach),解映射(detach)
  • 线程

  • 第二个参数可以传个NULL,第四个参数是给第三个参数的函数传参的,如果第三个参数的函数参数为void *,第四个参数就直接NULL
  • 线程函数的程序在phtread库中,故链接时要加上参数-lphread,也就是在编译的时候要,gcc xx.c -o xx -lphread
  • 第二个参数是保存子线程的退出状态值,如果不接受则设置为NULL
  • 左上图中的线程函数中的返回值就是子线程的退出状态值,右上图的输出结果就为666,pthread_exit(&num)这个函数的参数也类似,也是返回退出状态值,同样是在pthread_join中的第二个参数使用
  • 这个pthread_detach函数看似加不加没区别,不加也能正常执行,只是不加的话,子线程退出时系统没有回收资源,肉眼看不出来,所以最好加上
  • int pthread_cancel(pthread_t thread)线程取消
  • 上面的第二个参数可以NULL,这个函数在线程函数内部用
  • void pthread_testcancel(void) 设置线程取消点的函数,在线程函数内部用,在外部仍然要用pthread_cancel(thread)发送取消信号 
  • bzero()是把字符串内容清空
  • 总之,调用清理函数,当你push时,还没进行调用,只有出现上面三种情况,才会调用 
  • 同步是在互斥的基础上加上顺序
  • int pthread_mutex_lock(pthread_mutex_t *mutex);对互斥锁上锁,若已经上锁,则调用者一直阻塞到互斥锁解锁
  • int pthread_mutex_trylock(pthread_mutex_t *mutex);对互斥锁上锁,若已经上锁,则上锁失败,函数立即返回;
  • int pthread_mutex_lunlock(pthread_mutex_t *mutex);对互斥锁上锁,若已经上锁,则调用者一直阻塞到互斥锁解锁
  • 第一步,定义pthead_mutex_t mymutex; 第二步,初始化pthread_mutex_init(&mymutex);第三步,分别在两个线程里上锁,第四步,分别在两个线程里解锁
  • int sem_wait(sem_t *sem)信号量-1,若<=0,会引起调用者阻塞
  • int sem_trywait(sem_t *sem)信号量-1,若<=0,则操作失败,函数立即返回
  • int sem_post(sem_t *sem)信号量+1,发出信号唤醒等待线程
  • int sem_getvalue(sem_t *sem,int *sval),获取sem标识的信号量的值,保存在sval中
  • int sem_destroy(sem_t *sem)销毁
  • char *str; putchar(str); fflush(stdout) ; str++; 这个会一个个字符的输出
  • 无用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值