c mysql 删除一行_本文帮你在Unix玩转C语言

-rw-rwSrw- S表示设置组ID【有效用户ID和组ID】位已设置【有效用户ID变成文件所有者的ID】,同时,组执行位则未设置。

linux交换区==windows下虚拟内存

chmod a+t 目录 设置粘住位

粘住位:可执行程序正文副本保存在交换区。目录设置了粘住位,只有对目录有写权限加上1.拥有文件;2.拥有目录;3.root三种之一 才可以删除或更名目录下的文件。

chown fchown lchown更改文件用户ID

truncate(pathnane, length) ftruncate(filedes, length) 截断文件或创建空洞

磁盘可分为多个区,不同的区有不同的文件系统。

目录项【目录/文件名】->i节点->实际数据块。多个目录项可以指向同一个i节点,例如软连接和目录本身指向的是同一块数据,就应该指向的是同一个i节点。mv只更改目录名,不移动实际数据。

link(existpath, newpath)创建一个新的目录项,增加链接数;unlink(pathname)删除目录项,将pathname所引用的文件链接数减1. 目录项删除后看不见文件,但文件仍有可能占据磁盘空间直至被内核删除。

./a.out & 表示后台运行

如果打开文件的进程数和链接数同时为0,内核会删除该文件。

remove(pathname)解除对一个目录或文件的链接。rename(oldname, newname)

普通目录项和文件本身的关系是硬链接,她直接指向文件的i节点。符号链接是指向一个文件的间接指针,可以跨不同的文件系统。要注意函数是否跟随符号链接。

symlink(actualpath, sympath)创建符号链接。readlink(pathname, buf, bufsize)打开链接本身,并读链接中的名字。

ls -lt默认按文件修改时间排序,-u按访问时间,-c按更改状态时间。utime(pathname, times)更改文件的访问和更改时间。

mkdir(pathname, mode)创建一个新的空目录。rmdir(pathname)删除一个空目录。

DIR opendir(pathname) struct direntreaddir(DIR *dp) chdir(...)【当前工作目录是进程的一个属性,chdir只影响进程本身】 fchdir(...) getcwd(...)获得完整绝对路径

标准I/O库【ISO C标准】文件操作围绕文件描述符,也可以理解成围绕流(stream)。当用标准io打开或创建一个文件时,我们已使一个流与文件关联。标准IO最终都要调用read,write。

FILE结构包含:文件描述符、缓冲区指针、缓冲区长度、当前缓冲区字节数以及出错标志。文件指针是FILE*

标准输入输出的文件指针是stdin,stdout,stderr。io库提供缓冲的目的是减少使用read和write的调用次数。标准io函数通常调用malloc获得缓冲区。

setbuf(FILE, buf, mode ,size)更改缓冲类型。 fflus(FILEfp)此函数使该流所有未写的数据都被传送至内核。

FILE *fdopen(filedes, type)使已有的文件描述符和流关联。

FILE freopen(pathname, type, FILErestrict fp)在一个指定的流上打开文件,若流已打开,先关闭流。一般用于将指定文件打开为一个预定义的流:输入,输出,错误。

FILE *fopen(pathname, type【r+b,加号表示读和写】)打开一个指定的文件,b区分文本和二进制,对unix无用。 cache中用的都是open

int fclose(FILE *fp)关闭一个打开的流。

读写结构fread fwrite

一次一行fgets fputs

一次一个字符getc(FILEfp) fgetc(FILE fp) getchar(void) getchar等价于getc(stdin)。 出错或到达文件尾,三个函数返回同样的值,为了区分需要ferror(FILE fp) feof(FILEfp) void clearerr(FILE *fp)

int ungetc(int c, FILE *fp)将字符再压送回流中。

一次一个字符输出函数putc(int c, FILE) fputc(int c, FILE) putchar(int c)

调用函数时间长于调用宏;一次系统调用比普通函数调用更费时间。

每次一行io的函数:char fgets(buf,n,FILE)从指定流读。 chargets(buf)从标准输入读。 输出:fputs(str, FILE) puts(str)

二进制IO:size_t fwrite(&struct[2], sizeof(struct), 4, FILE* fp) 将一个数组的第2-5号元素写在一个文件上

fread(..) 只能处理统一系统上的数据,异构系统通过网络互连时不行,不同系统间交换二进制数据需要使用较高级的协议。

定位流:ftell(FILE) fseek(FILE, offset, whence【SEEK_SET】) rewind(FILE*) fgetpos(..) fsetpos(...) 文件描述符是用lseek

int fileno(FILEfp)获得文件描述符 , FILE tmpfile(void)创建临时文件

$TMPDIR=.. ./a.out 在程序名前指定环境变量

int printf(format,...)将格式化数据写到标准输出。 vprintf(format, va_list arg) vfprintf(...,va_list arg) vsprintf vsnprintf 可变参数表(...) 变成了arg

int fprintf(FILE* fp, format, ...)写至指定的流

int sprintf(buf, format)将格式化的字符串写入数组buf中,在数组尾端自动加null字节

int snprintf(buf, size_t n,format, ...) 与sprintf基本一样,n指定了缓冲区长度,超过就丢弃避免溢出

int scanf(format, ...) sscanf(cmdline【源】, "%s %s", opt[0], opt[1]【目的】)

int fscanf(FILE *fp, format, ...)

int sscanf(buf, format, ...) vscanf(format, va_list arg)等等

struct passwd getpwnam(const char name)获取口令文件项

struct tm结构用于保存时间的年月日的形式。

gettimeofday(struct timeval *res, NULL)微秒级

time_t time(time_t* calptr)返回当前时间,calptr不空,时间值放其中。

struct tmlocaltime(const time_t ptr)他和gmtime(..)的区别是他把日历时间转换为本地时区时间,gmtime转换成国际标准时间。

time_t mktime(struct tm* ptr)以本地时间作为参数,将其转换为time_t值【日历时间:1970至今】。

char asctime(struct tm)返回指向年月日字符串的指针。char ctime(time_t * prt)返回指向日历时间的指针。

size_t strftime(...)按格式控制时间字符串

timeval指定秒和微秒、timespec指定秒和纳秒

正常终止一个程序:exit()默认包含关闭流操作【FILE存储区清0】 在main中exit(0)等价于return(0)

int atexit(void (*func)(void))登记的函数会被exit函数以相反的顺序调用。

内核执行程序的唯一方法是exec。进程自愿终止的唯一方法exit【显式或隐式】。非自愿的需要给一个信号终止。

extern char **environ环境指针 getenv putenv 访问特定环境变量

a.out的符号表段、调试信息段、动态共享库链接表段不装载到进程执行的程序映像中。 size a.out 报告正文段、数据段、bss段的长度

cc -static hello1.c 阻止使用共享库。 cc默认使用共享库

void* malloc(size_t size)存储区初始值不确定

void* calloc(size_t nobj, size_t size)为指定数量指定长度的对象分配存储区,初始化为0

voidrealloc(void ptr, size_t newsize)更改以前的长度,新增部分初始值不确定,老部分保留内容。

void free(void* ptr)

goto语句不能跨越函数,setjump longjmp可以处理嵌套调用中出错情况【否则只能检查返回值逐层返回麻烦】。在希望返回的位置int setjmp(jmp_buf env【env为全局才多个函数可见】),出错位置int longjmp(env,8)。

"str1" "str2"等价于"str1str2"。为IO库分配缓冲区应全局静态或动态alloc分配。

编译器进行优化时,它有时会取一些值的时候,直接从寄存器里进行存取,而不是从内存中获取,这种优化在单线程的程序中没有问题,但到了多线程程序中,由于多个线程是并发运行的,就有可能一个线程把某个公共的变量已经改变了,这时其余线程中寄存器【线程各自有寄存器】的值已经过时,但这个线程本身还不知道,以为没有改变,仍从寄存器里获取,就导致程序运行会出现未定义的行为。

自动变量不想回滚,可以定义为volatite【易失】属性。易失属性告诉编译器不要优化,在其他地方会改变值,优化可能将这个变量一直放到寄存器中。

int getrlimit(int resource, struct rlimit *rlptr) setrlimit可以查询和更改资源限制。shell中的ulimit。

getpid getppid【获得父进程id】 getuid geteuid getgid getegid【有效组id】

pid_t fork(void) fork返回两次 clone,父返子,子返0.父子进程执行fork之后的代码,父子共享正文不共享数据,共享文件表和i节点。写时复制(copy-on-write)写时复制,只读时共用。

vfork在子进程调用exec或exit之前,他在父进程的空间中运行,调用exec或exit之后父进程才继续运行。

标准IO库printf是带缓冲的。标准输出连到终端是行缓冲【打印】,否则是全缓冲。定向到文件是全缓冲

信号可由进程自身产生【abort】、其他进程【kill(pidid,sig)】或内核产生。

父进程提前终止的的子进程由init【init中默认有wait】进程领养。内核为每个终止的子进程保存了一定量的信息,父进程用wait或waitpid得到这些信息。

一个长期运行的进程fork很多子进程,除非手动wait,否则会出现很多僵死进程。

pid_t wait(intstatloc) pid_t waitpid(pid_t pid【等待pid号进程】, int statloc【指向终止状态】, int options)【成功返回进程id、0、失败返回-1】。 如果收到SIGCHLD信号调用wait,可以立刻返回,如果任意时刻调wait,可能会阻塞直到有一个子进程终止。

wait3 wait4比waitpid多了一个功能是最后一个参数会返回所有子进程使用资源情况的汇总。

竞争条件:多进程处理共享数据,数据的结果和处理顺序有关。父等子死用wait,子等父死 【轮询】while(getppid() != 1) sleep(1);等于1是init进程id。为1说明父进程死了,被init接管了。

exec不创建新进程,进程ID不变。exec只是用一个全新的程序替换当前进程的正文、数据、队、栈。execl execv execle execve execlp execvp

所有.c文件查找字符串abort的指令$ grep abort .//.c

任何时候都可以调用int setuid(uid_t uid)做下两种操作:有效用户ID=实际用户ID;有效用户ID=保存的设置用户ID【exec复制有效用户ID得来的(一般是文件所有者?)】。设置用户ID的程序,fork后,exec之前要改回普通权限,不应使用system函数。

suspend $fg 作业控制

shell中awk实际是shell先fork->exec(awk)->wait来运行的。

char* getlogin(void)获取登录名。找到运行该程序的用户登录名getpwuid(getuid())

网络登录telnetd进程fork,父负责网络连接的通信,子执行login,父子间通过伪终端相连接。

进程组是一个或多个进程的集合。getpgid setpgid设置指定进程或调用进程的组ID。

会话是一个或多个进程组的集合。进程调用pid_t setsid(void)建立一个新会话。进程是首进程、组长、断开所有控制终端。pid_t getsid(pid_t pid)返回会话首进程的进程组ID。

secureCRT是终端,对应前台进程组【终端(终端也是文件描述符)关联的进程】,控制进程组【shell】,后台进程组【&让其后台运行】,加在一起是会话。

一个作业是几个进程的集合,通常是一个进程的管道线。vi main.c【前台启动了一个作业】 pr *.c | lpr & | make all & 【后台启动了两个作业,两个作业调用的所有进程都后台运行】

终端驱动程序产生信号进而影响前台进程组的方法:中断字符ctrl+C 退出字符ctrl+\ 挂起字符 ctrl+Z。 可以用信号使后台作业暂停,fg %1 使1号作业转为前台作业

进程属于进程组,进程组属于一个会话,会话可能有也可能没有控制终端。前台进程组ID是终端的属性,不是进程的属性。

管道线的最后一个进程是shell的子进程,执行管道的其他命令都是最后一个进程的子进程。前端进程组ID==sessionID时说明他是后台进程。

不是孤儿进程组的条件:该进程组中有一个进程,其父进程属于同一个会话的另一个组。

信号SIGKILL SIGSTOP不能忽略,不能捕捉。

core文件复制进程终止时的存储映像。

kill命令和kill函数只是将一个信号送给一个进程或组,进程是否终止取决于信号的类型,以及进程是否安排了捕捉该信号。$kill -USR1 7216

void (signal(int signo, void (func)(int)))(int)成功返回信号以前的处理配置,失败返回SIG_ERR。不改变信号的处理方式,就不能确定信号当前的处理方式。func指定SIG_IGN或SIG_DEL表示忽略或默认处理。

exec使捕捉失效,捕捉函数的地址可能无意义。

进程捕捉到信号执行信号处理函数func,执行完后执行发生信号时正在执行的代码【pause函数能使进程挂起直到捕捉到一个信号】。处理第一次信号后是否将信号动作复位为默认值?

read write部分数据时被中断算成功还是失败可以选择。

在信号处理程序中调用一个不可重入函数,结果是不可预见的。

raise(int signo) == kill(getpid(), int signo) 进程将信号发送给其他进程需要权限。向一个不存在的进程发空信号,kill返回-1.

进程ID会重新使用。

signal函数的语义与实现有关,最好使用sigaction函数。sigaction(signo【要检测或修改的具体动作的信号编号】, &act【非空则修改其动作】, &oact【非空则返回信号的上一个动作】)

sigemptyset(&act.sa_mask)【初始化由set指向的信号集清除其中所有信号】

在处理一个给定的信号时,如果这种信号再次发生,通常并不将他们排队,会被阻塞到对前一个信号处理结束为止。阻塞结束后内核只传递这种信号一次。【屏蔽字为0代表没有信号阻塞,执行哪个信号的处理函数屏蔽哪个信号】

unix低速系统调用阻塞期间【磁盘IO一般不阻塞】如果接受到一个信号,则该低速系统调用被中断。

void abort(void)使异常程序终止。子进程终止会向父进程发送SIGCHLD信号。sig2str str2sig是信号编号和信号名相互转换函数。

多线程程序在单处理器运行仍然能改善响应时间和吞吐量。

线程ID只在它所属的进程环境中有效,因此可以不唯一。

pthread_t pthread_self(void)获得自身线程的ID。主线程可以用线程ID控制哪个线程处理哪些作业。新线程和主线程之间有竞争,使用主线程返回的线程id并不安全。线程ID如果很长那估计是地址。

如果任一线程调用exit,_Exit,_exit整个进程就会终止。线程终止方式:1.启动函数返回。2被同进程其他线程取消【线程可以忽略取消】。3 pthread_exit

void pthread_exit(voidrval_ptr) int pthread_join(pthread_t thread, void* rval_ptr【保存线程的终止状态】)【阻塞直到线程返回】

线程里面声明的东西别往出带。线程从线程函数返回终止,清理程序就不被调用。waitpid==pthread_join。pthread_detach使线程分离【对线程终止状态不感兴趣】,分离线程终止时资源被回收,分离的线程无法pthread_join。

加锁的一种场景:对引用计数加1、减1以及检查是否为0之前都要锁住互斥量。【引用数类似文件的link】

读写锁以读模式锁住是共享模式【并发读】,以写模式锁住是独占模式【独自写】。

线程的虚拟地址空间是多个线程共用,如果线程多,会不够用。递归类型互斥量可以递归加锁。

线程和信号都涉及函数可重入的问题。信号:捕捉函数如果向全局数据写会错。线程:多个线程同时调用同一函数。每个线程有各自的信号屏蔽字。信号处理函数进程内共享。

errno被重新定义为线程私有数据。键用来保护线程私有数据。

包含多线程的进程fork时只有fork的线程被复制进子进程,锁的情况无法控制,如果马上exec就可以避免。

pread(...)使偏移量的设置和数据读取成为一个原子操作。

ps -a【显示其他用户所拥有的进程状态】x【没有控制终端的进程状态】j【会话ID、进程组ID。。】

创建守护进程两次fork,就不是会话首进程,不会取得控制终端。fork保证子进程不是进程组组长,可以setsid。

lockfile(fd)对文件加锁 lockf(lockfd, F_TLOCK, 0L)可以确保只有一个守护进程运行。

低速系统调用是可能会使进程永远阻塞的一类系统调用。

非阻塞IO:操作无法完成,立即出错返回【不停在那,以便进行下一步处理,类似trylock试加锁】。两种方法指定描述符为非阻塞IO:open时O_NONBLOCK;fcntl(fd, cmd, &lock)打开 O_NONBLOCK标志。

记录锁==字节范围锁:当一个进程读或修改文件某部分时,可以阻止其他进程修改同一文件区。有些系统中文件的最后状态取决于写该文件的最后一个进程。

同一进程可对同一字节范围重复加锁,新锁换老锁。可以测试另一个进程是否对某记录加锁。

锁是与进程、文件两者相关联的。fork出的子进程不继承父进程对文件的锁【避免父子同时写一个文件】。exec新程序继承原程序的锁。

某些unix提供系统调用跟踪特性。

STREAM:构造内核设备驱动程序和网络协议包的一种通用方法。

IO多路转接【两个描述符】:执行阻塞read,阻塞是对整个进程阻塞,如果多个通路【一般是无限循环读、写】想要相互不影响,就得fork多个进程,每个进程处理各自的文件描述符。用非阻塞read轮询描述符消耗cpu。

IO多路转接思想:构造一张描述符表,调用一个函数,直到表中描述符中的一个已经准备好IO时,该函数返回,告诉进程哪些描述符可以IO。主要用于终端IO和网络IO。select(0, NULL, NULL, NULL, &tv)相当于sleep了,精确到微秒。

异步IO:基本思想,告诉内核,当一个描述符已准备好可以进行IO时,用一个信号通知它【它指应用程序】。系统V异步IO调ioctl设置信号处理,只对STREAMS设备和STREAMS管道起作用。 BSD异步IO设置信号SIGIO处理程序,调fcntl设置O_ASYNC文件为异步IO。只对终端和网络描述符有效。

存储映射IO:【将一个给定文件映射到一个存储区域】unsigned charmmapBuf = (unsigned char)mmap(NULL【区域起始地址】, fileSize, PROT_READ【映射区可读】, MAP_SHARED ,fd【被映射文件】, 0【映射字节在文件中起始偏移量】) munmap((char*)mmapBuf, fileSize)【解除映射】 msync冲洗到磁盘

IPC【InterProcess Communication】:各种管道、消息队列、信号量、共享存储、套接字、STREAMS【仅后两种支持不同主机进程间通信】

管道:半双工【数据只能在一个方向上流动】;只能在公共祖先的进程间使用,通常fork后父子间使用。int pipe(int filedes[2]) fork后f[0]

sh -c cmdstring表示shell将扩展字符串中的特殊字符【*.c】。

${PAGE:-more}如果PAGE已定义,使用,否则用more。

对管道标准IO默认全缓冲。

通过FIFO【命名管道】不相关的进程也能交换数据。int mkfifo(pathname, mode_t mode)类似于创建普通文件。

创建IPC结构:msgget semget shmget 要指定一个键key_t。 ftok可由一个路径名和项目ID产生一个键key_t ftok(path, id)

msgctl semctl shmctl修改uid、gid、mode 三种IPC都有内置限制,可通过配置内核修改。 ipcs查看 ipcrm删除

msgrcv可以是非先进先出

信号量的值代表对应资源是否可以使用。semop(_ID, buf[]【数组中操作要么都执行,要么都不执行】, 1)表示等待信号量、释放资源、获取资源。semctl取信号量信息、设置信号量信息。

使用信号量【实际上是同步原语而不是IPC】,先创建一个包含一个成员的信号量集合,信号量值赋初值1.分配资源时sem_op为-1调用semop,释放资源sem_op为1调用semop。每次设置SEM_UNDO,以处理进程终止还有未释放资源的情况。

shmget既可以创建,也可以引用已有的【msgget一样】。 shmctl IPC_RMID减少引用数,不真正删除。shmid和pickey不一样,shmget返回值是shmid 。shmdt脱接不删除,引用数减一。

套接字用于不同计算机上的进程相互通信,其它进程运行位置透明。可以采用许多网络协议,TCP/IP常见。

创建一个套接字int socket(int domain【例如ipv4internet网域】, int type, int protocol)返回套接字文件描述符。

int shutdown(int sockfd, int how)禁止套接字上的输入输出。uint32_t htonl(uint32_t hostint32)等进行处理器字节序和网络字节序的转换。

inet_pton( AF_INET, host.c_str(), &m_addr.sin_addr)将文本字符串转换成网络字节序的二进制地址

poll select函数能检查文件描述符的状态,用来决定是否对文件描述符执行某种操作。

setsockopt(_sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len)

int fattach(int fileds, const char* path)使STREAMS管道和文件系统中的一个名字关联。

unix域套接字用于同一机器上进程间通信。int ssocketpair(int domain, int type, int protocol, int sockfd[2])

终端IO:函数tcgetattr tcsetattr 终端IO控制函数大多tc开头

很多数据库实现都采用两个文件:索引文件和数据文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值