linux c编程复习笔记11-14章

大四,找工作前重新整理一下过往的Linux c编程知识
本人之前学的是《linux高级程序设计》加一些网上看的文章博客,翻了一些《Unix环境高级编程(第二版)》和《Unix网络编程》玩
此次系统巩固下, 完整阅读下《Unix环境高级编程(第三版)》(虽然和第二版相比没什么多少改动 (=^ ^=)),为找工作做些准备。


记录下已生疏的点和当时学得不深的点,以及一些值得探究的点
作为一个补充记录。

linux c编程复习笔记1-10章

http://blog.csdn.net/young0boy/article/details/52814750



-------------------2016年10月25日 09:08:03----------
调试了这么久才搞定。快一年没怎么动手敲这种代码了,相当生疏


pthread_sigmask()
对线程处理的信号屏蔽函数。


在主线程中加入信号屏蔽,在子线程中用sigwait(&mask,&signo)释放,让只有该子线程可以进行信号处理。




子线程在fork后,依然是复制整个进程空间,同时继承互斥读写锁等,若不是马上调用exec函数族,那么就需要马上清除锁
使用pthread_atfork(void (*prepare)( void),void(*parent)(void),void (*child)void);
preapare 在fork之前调用,parent是在fork之后、返回之前在父进程中调用,child则是在子进程中调用



-------------------2016年10月24日 08:50:01----------
void *pthread_getspecific(pthread_key_t key)
int pthread_setspecific(pthread_key_t key, void *val)

得到和设置与key关联的内容



研究malloc、free算法实现,关键是如何查找和处理碎片
http://blog.codinglabs.org/articles/a-malloc-tutorial.html
觉得这个大神说的很好。


实现代码的时候,突然想到了平时忽略的地方
c其实根本不分什么指针和其他变量,从本质来说都是变量,指针只是用的((变量表示的存储值)表示的内容)
这点能从汇编代码看出来的,表达不清,只能用这种()这种方式表示优先和重点




-------------------2016年10月22日 14:11:02----------
pthread_attr_getstacksize()
**_attr_setstacksize()
设置默认栈区大小,


同一个线程可以多次获取同一个递归锁,不会产生死锁。而如果一个线程多次获取同一个非递归锁,则会产生死锁。
Linux下的pthread_mutex_t锁默认是非递归的。
可以显示的设置PTHREAD_MUTEX_RECURSIVE属性,将pthread_mutex_t设为递归锁。
MutexLock mutex;      
void foo()  
{  
	mutex.lock();  
        // do something  
        mutex.unlock();  
}     
void bar()  
{  
       mutex.lock();  
       // do something  
       foo();  
       mutex.unlock();   
}  

当一个线程调用bar()函数的时候,若是非递归锁,那么立即锁死。


读锁是递归锁,写锁是非递归锁
#include "unix.h"
#include <pthread.h>
int main()
{
  pthread_rwlock_t rwl;
  pthread_rwlock_init(&rwl,NULL);
  pthread_rwlock_rdlock(&rwl);
  pthread_rwlock_rdlock(&rwl);
  pthread_rwlock_unlock(&rwl);
  pthread_rwlock_unlock(&rwl);
  pthread_rwlock_destroy(&rwl);  
  printf("yes\n");
  return -1;  
} 


函数的可重入很重要,线程安全,信号安全等等。
尽量避免使用全局变量,静态区。


使用pthread_once(pthread_once_t *a,void *fun)
a必须为全局或者静态变量,必须初始化为PTHREAD_ONCE_INIT;
保证fun函数只执行一遍


-------------------2016年10月22日 09:49:07----------
prthread_detach(pid)在线程终止后,立马回收资源。
pthread_attr_setdetachstate(*attr,int *stat)
**_**_getdatachstate(*attr,int *stat)


**_attr_getstack(* attr,void *stakcktaddr,size_t sksize)
**_atrt_setstack()
若栈空间用完了,可用malloc或者mmap分配新的空间



-------------------2016年10月21日 14:44:21----------
pthread_mutex_timedclock()
若不能加锁,愿意等待的阻塞指定时间




读写锁
pthread_rwlock_init(pthread_rwlock_t,const pthread_rwlockattr_t *attr)
**_**_destroy(pthread_rwlock_t)



屏障
pthread_join是一种屏障,等待其他线程到达一点后,继续执行
pthread_barrier_init(pthread_barrier_t *barrier,pthread_barrierattr_t *attr,int count)
pthread_barrier_wait( ** *barries)


barries 初始化+1,表示主线程等待其他完成




-------------------2016年10月21日 10:15:07----------
进程退出atexit连宏函数都不是
#  define pthread_cleanup_push(routine, arg) \
  do {                                                                        \
    __pthread_cleanup_class __clframe (routine, arg)


/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
   If EXECUTE is non-zero, the handler function is called. */
#  define pthread_cleanup_pop(execute) \
    __clframe.__setdoit (execute);                                            \
  } while (0)


互斥锁
pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t * attr)
pthread_mutex_destroy(pthread_mutex_t *mutex)


pthread_mutex_lock(pthread_mutex_t *mutex)
**_**_trylock()非阻塞加锁
**_**_unlock()解锁



-------------------2016年10月20日 18:33:39----------
 对系统来说,cpu资源的分配和调度是分开的,即进程和线程。
 以前是一起,即进程 。



-------------------2016年10月20日 13:54:01----------
void *mmap(void *addr ,size_t len,int prot,int flag,int fd,off_t off)
此函数依赖系统虚拟页,若文件长度12,页长512,后面500补齐0,更改无效,需要先加长文件
返回的才是真正可用空间
prot 指定读写执行权限
addr作为分配的起始空间,一般作为一种建议(flag参数 MAP_FIXED标志,表示使用这一个地址,否则只是建议。这标志位影像移植性)


mprotect(void *addr,size_t len,int prot)修改映射空间权限。


msync(void *addr,size_t len,int flag)想到与flush
MS_SYNC参数同步
munmap(void *addr,size_t len)关闭缓冲区,并不马上刷新


单纯的普通文件,在速度上并没有优势。,甚至可能还有劣势,在内存页的管理开销上很大,而read等则在系统调用在内核和用户空间的内存拷贝开销较大
从网上看了一些讨论,发现主要取决一些程序员的用法,如果需要操作整个文件,全部内容,read可能效率还高点。
  大家关于“mmap()”更快的认识来自于 read() 是需要内存拷贝的;
当今硬件技术的发展,使得内存拷贝消耗的时间已经极大降低了;
但“mmap()”的开销在于一次  pagefault,这个开销相比而言已经更高了,而且 pagefault 的处理任务现在比以前还更多了;
而且,mmap之后,再有读操作不会经过系统调用,在 LRU 比较最近使用的页的时候不占优势;
于是,普通读情况下(排除反复读之类的文艺与2B读操作),read() 通常会比 mmap() 来得更快。


对于400M文件的复制
root@kali:/home/lee/123# time ./io

real    0m0.014s
user    0m0.000s
sys     0m0.000s
root@kali:/home/lee/123# time ./mmap

real    0m1.374s
user    0m0.068s
sys     0m0.452s



-------------------2016年10月20日 08:37:16----------
如果进程还要处理其他事物,不想被io阻塞,可以使用异步io(同步非阻塞也可以)
在完成所有事物后,异步操作未完成时,可以用aio_suspend 函数阻塞进程,直至操作完成.
也可以用aio_cancle()进行函数取消
异步io有待加强




readv() 和 writev()对于多段缓存,系统开销较小
依次对缓冲区读写,感觉实质是一次读完所有,分段缓存,但对于书中第二种方式快的原因仍无法理解。
等待看到20.8节。


针对网络等设备出现未读到终结,操作所返回的数据可能少于所要求的数据,作者写readn函数,实质是循环调用
writen一样


-------------------2016年10月19日 19:12:27----------
I/O多路转接貌似至今还不是POSIX的组成部分。


pselect 调用的时间结构体在系统支持的情况下,比select更精确
加入的信号屏蔽关键字,在函数返回时回复,属于原子操作




-------------------2016年10月19日 13:31:10----------
精灵进程,用一个写锁文件,确保没有副本产生


建议性锁和强制性锁
建议性锁不锁定文件,open、read write依然可以操作
强制性锁锁定文件,每次open,read,系统都要验证锁的可操作性
posix未有规定 强制锁
linux 上要 需要手动开启强制性锁:
必须: 1、对要加锁的文件执行 chmod g+s; chmod g-x (Sys V 强制锁)
2、该文件所在的文件系统在 mount 的时候,加选项: mand 。mount -o mand 


流(设备,非io流)牵扯到驱动,未明白


-------------------2016年10月18日 19:07:08----------
fcntl()函数文件所 
所加载的区域可以超过文件尾,但不能超越文件头
另外,锁的长度为0,表示加锁整个文件,包括未来部分。
fd1 = open(pathname ,);
write_lock(fd1,0,SEEK_SET,1);
if( fork() >0)
{
    fd2 = dup(fd1);
    fd3 = open(pathname,);
    pause();
}else{
    read_lock(fd1,1,SEEK_SET,1);
    pause();
}  


--链表存在v节点尾
父进程中,关闭fd1、fd2和fd3中的任意一个都将释放由父进程设置的写锁
内核会从该描述符所关连的 i节点开始,逐个检查flock连接表中各项,并释放由调用进程持有的各把锁。内核并不清楚也不关心父进程是用哪一个描述符来设置这把锁的




-------------------2016年10月18日 08:47:57-----------
isatty(fd)判断是否是终端文件
实现:
struct termios term;
return (tcgetattr(fd,&term)!=-1);


getpass函数,在终端禁止回显


对当前终端窗口的大小进行跟踪,在窗
口大小发生变化时,使内核通知前台进程组。
内核为每个终端和伪终端保存一个winsize结构。
用ioctl函数的TIOCGWINSZ和TIOCCWINSE命令获取和改变他。
当该结构体改变时,内发发送一个信号 SIGWINCH给应用程序。



-------------------2016年10月17日 18:47:33------------
tcgetattr取属性(termios结构)
tcsetattr设置属性(termios结构)
cfgetispeed得到输入速度
cfgetospeed得到输出速度
cfsetispeed设置输入速度
cfsetospeed设置输出速度
tcdrain等待所有输出都被传输
tcflow挂起传输或接收
tcflush刷清未决输入和/或输出
tcsendbreak送BREAK字符
tcgetpgrp得到前台进程组ID
tcsetpgrp设置前台进程组ID


在POSIX.1的11个特殊字符中,可将其中9个更改为几乎任何值。不能更改的两个特殊字符是新行符和回车符(\n和\r)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值