Unix 环境高级编程-读书笔记

每个线程都有属于自己的局部errno,避免一个线程干扰另一个线程.

使用出错信息:

#include<iostream>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
int main(int argv,char* argc[])
{
	fprintf(stderr,"EACCES: %s\n",strerror(EACCES));//strerror()把整形转出错值转换成对应含义的字符串.
	errno=ENOENT;
	perror(argc[0]);//先打印输入的字符串值,然后打印当前的出错信息
	exit(0);
}

将标准输入复制到便准输出

while((n=read(STDIN_FILENO,buf,buffersize))>0)
{
	write(SRTDOUT_FILRNO,buf,n);
}
用法: ./a.out < infile > outfile

用户ID是0的用户是root用户. 


在notepad++中自动补全功能.http://rabbit52.com/2012/devel/notepad-autocomplete-brackets

时钟时间,是程序远行时间的总量.用户时间.


2013年3月1日16:51:53


我们直接使用系统调用或者库函数,但是库函数会有自己的系统调用, 在必要的时候我们可以自己定义自己的库函数.

POSIX 定义的必需的头文件 http://www.cnitblog.com/guopingleee/archive/2007/08/13/31701.html


2013年3月1日20:51:25


在函数中使用省略号表示 余下参数的数量和类型根据具体的掉用有所不同.

列如

#include<fcont1.h>
int opent(const char * path,int flag,...)
在这个函数当中只有创建文件时才使用第三个参数.
#include<fcont1.h>
int creat(const char * pathname,mode_t mode);
//等价于
open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);
//等价于 ,创建一个文件 return 文件描述符 或者 -1
#include<unistd.h>
int close(int fildes);
//关闭文件 return 0 或者 -1 
#include<unistd.h>
off_t lseek(int fildes,off_t offset, int whence);
//设置文件偏移量 return 新的文件偏移量 或者 -1 
off_t currentPosition;
currentPosition = lseek(fd,0,SEEK_CUR) ;
//确定文件的偏移量


2013年3月2日13:08:02

od -c fileName
以字符方式打开文件, 就是显示里面所有字符的内容.

#include<unistd.h>
ssize_t read(int filedes, char * buf, size_t nbytes);
return 读取的字符数,文件尾返回0,出错返回1. 

#include<unistd.h>
ssize_t write(int filedes, const void * buf, size_t nbytes);
return 成功返回已经写入的字节数, 出错返回 -1
在将标准输入复制到标准输出的例子当中, linux ext2 文件系统的最好buffer size 是4096

#include<unistd.h>
int dup(int filedes);
int dup2(int filedes1,int filedes2)
//return 成功返回文件描述符,失败返回-1, filedes2用来指定描述符,这个描述符已经打开,那么关闭它然后打开,如果两个filedes是一样的,那么返回filedes.

#include<unistd.h>
int fsync(int filedes);
int fdatasync(int filedes);
void sync(void);
成功返回0,出错返回-1.

2013年3月2日19:37:04

#include<unistd.h>
#include<sys/ioctl.h>
#include<stropts.h>
int ioctl(int filedes,int request, ....);
//return 出错返回-1, 成功返回其他值.
//对于ISO C原型,它用省略号表示其余余数.但是,通常只有另外一个参数,它常常是指向一个变量或结构.
在命令中输入反斜杠\ 告诉shell 下一行继续输入命令



2013年3月6日10时32分38秒

当打开一个文件时,应当对文件绝对路径上的所有文件具有执行路径。

 

#include<unistd.h>
int access(const char * pathname,int mode);
//return 成功返回0,出错返回-1.
//用于测试文件的俄访问权限.

#include<sys/stat.h>
int chmod(const char *pathName,mode_t mode);
int chmodf(int filedes, mode_t mode);
//return 成功返回0,出错返回-1
//用于修改文件权限.



2013年3月6日16:25:34

#include<unistd.h>
int chown(char * pathName,uid_t owner,gid_t group);
int fchown(int filedes,uid_t owner,gid_t group);
int lchown(const char * pathName,uid_t owner,gid_t group);
//return 成功返回0,出错返回-1


普通文件的文件长度可以是0,目录文件的长度是的倍数,这个数可以是16或者256

ls -l
显示的是,文件的大小,包含空洞时也是一样的
du -s
显示的是文件占 用的磁盘空间块数(一个块可能包含若干个字节,256)
当用cat 复制文件时,文件中的空洞会被填补为\0

2013年3月6日14:48:47
ln -s 被指向文件 符号文件
用open()打开一个指定的符号文件.那么,会跟随符号链接到达指定的文件,如果文件不存在则出错.

解释了stat的结构和各种读写权限还有宏定义

http://blog.csdn.net/gdujian0119/article/details/6363574



2013年3月15日16:40:09

在编译多线程的程序的时候,要注意带 -pthread 参数,否则会出现

undefined reference to `pthread_create'
g++ test_pthread.cpp -o test_pthread -g -pthread

2013年3月20日14:50:36

读写锁

写加锁---阻塞所有的加锁请求

读加锁--①允许读加锁  ②阻塞写加锁直到所有的线程都释放锁,并且阻塞写加锁来到

         

2013年3月23日0:53:38

今天终于把第三个实验做完了,真是的........怎么说呢,  很多感觉

n 定时服务器程序timer
l 利用信号SIGALARM,实现一个定时器服务器程序。请求者指定过期相对时间,timer接收到定时请求之后,在相对时间耗尽时通知请求者。要求使用异步方式,请求者不能被阻塞。
l 实现可能用的机制:PIPE, 多进程,信号

/*
 * =====================================================================================
 *
 *       Filename:  pipe.cpp
 *
 *    Description:  test pipe, comunicating between father thread and child thread
 *                  要做的是,开始,子进程发送一个整形数据给父进程,以在时间到达之后用产生一个超时信号
 *                  父进程在接到信号时候开始计时,在给定时间内产生一个超时信号.
 *
 *        Version:  1.0
 *        Created:  03/20/13 16:52:43
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  
 *        Company:   *
 * =====================================================================================
 */
#include<iostream>
#include<string.h>
#include<signal.h>
#include<unistd.h>
#include<sys/time.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
using namespace std;

int childPid;//不得已而为之的全局变量

static void catchSignal(int signalNo) 
{
    if(signalNo==SIGALRM)
    {
      kill(childPid,SIGALRM);
    }
    else
    {
        cout<<"caught a wrong signal"<<endl;
    }
}

static void childReceive(int signalNo)
{
    if(signalNo==SIGALRM)
    {
        cout<<"child received !!!"<<endl;
    }
}
int main(int argc,char *argv[])
{
    int n;
    int fd[2];
    pid_t pid;
    char line[2];//communicate between pipe

    if(argc!=2)
    {
        cerr<<"usage: command args"<<endl;
        exit(-1);
    }
    if(pipe(fd)!=0)//在pipe中0读,1写 
    {
        cerr<<"error eccure when pipe"<<endl;
        perror("reason : ");
        exit(-1);
    }
    if((pid=fork())<0)
    {
        cerr<<"erro when fork "<<endl;
        exit(-1);
    }
    else if(pid==0)//在子进程中,使用pipe把要设置的时间发送给父进程
    {
        memset(line,0,sizeof(line));
        strcpy(line,argv[1]);
        close(fd[0]);

        write(fd[1],line,strlen(line));
        cout<<"child pid :"<<getpid()<<endl;
        if(signal(SIGALRM,childReceive)==SIG_ERR)
        {
            cerr<<"in child, caught error"<<endl;
            perror("reason : ");
        }
        pause();
    }
    else if(pid>0)
    {
        childPid=pid;
        close(fd[1]);
        memset(line,0,sizeof(line));
        read(fd[0],line,sizeof(line));
        int kickCount=line[0]-'0';
        cout<<"from child :"<<kickCount<<endl;

        struct itimerval value;
        struct itimerval oldValue;
        value.it_interval.tv_sec=kickCount;
        value.it_interval.tv_usec=0;
        value.it_value.tv_sec=kickCount;
        value.it_value.tv_usec=0;
        cout<<"time counter begin to work"<<endl;
        setitimer(ITIMER_REAL,&value,&oldValue);
        cout<<"in parent, child's pid"<<pid<<endl;
        if(signal(SIGALRM,catchSignal)==SIG_ERR)
        {
            cerr<<"parent can't caught a signal"<<endl;
        }
        cout<<"waitpid: "<<waitpid(pid,NULL,0)<<endl;
    }
}

工作过程是, 子进程在开始的时候,通过管道给父进程发送一个整数,该整数是希望在多少秒之后子进程能收到父进程的通知, 这里把这个通知假设为超时信号.  事实上,在父进程中设置计时器,子进程是无法直接收到超时信号的,所以只好通过kill发送到子进程.  子进程接收到信号之后,说明已经接收到信号,然后返回并结束.


3.23 21:12

真NM火了, 那个互斥量是个球啊, 我日整天说本质上是一把锁,但是我更像知道是怎么把别的东西给锁起来的,  你MD讲来讲去就是在绕圈子,网上一大堆废物写了一大堆废码, 你抄我的,我抄你的, 说来说去就是那么写内容,   其实最不明白的是,吧互斥量分配在局部和分配在全局有什么区别,   看到他的用法是, 用一个lock 还有unlock把一部分代码包围起来,  被包围的代码就是一次只能有一个线程操作.    但是NMD ,搞这种有意思吗, 直接把互斥量这个概念去掉不就行了,非要去设置它干么.   就整一对函数, 要成对出现, 中间的数据就是被保护的, 传入的参数据定具体的保护措施,,, 你MD本来程序员就看不多具体实现,非要整那么多概念来忽悠人, 还有NMD条件变量,  思想根本就不是结构化,  都想搞特殊,那还要标准干嘛,,,,艹艹......

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值