![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
APUE
文章平均质量分 80
yuanzhangmei1
这个作者很懒,什么都没留下…
展开
-
文件描述符 和 流的关系
任何一种操作系统中,程序在开始读写一个文件的内容之前,必须首先在程序与文件之间建立连接或通信通道,这一过程称为打开文件。打开一个文件的目的可以是为了读或者为了写,也可以是即读又写。 UNIX系统中有两种机制用于描述程序与文件的这种连接: (1)文件描述符 (2)流文件描述符 和 流:相同点:1. 都是用来表示用户程序与被操作的文件之间的连接,并在此连接原创 2013-06-19 20:05:57 · 3947 阅读 · 2 评论 -
POSIX 线程详解
了解如何正确运用线程是每一个优秀程序员必备的素质。线程类似于进程。如同进程,线程由内核按时间分片进行管理。在单处理器系统中,内核使用时间分片来模拟线程的并发执行,这种方式和进程的相同。而在多处理器系统中,如同多个进程,线程实际上一样可以并发执行。那么为什么对于大多数合作性任务,多线程比多个独立的进程更优越呢?这是因为,线程共享相同的内存空间。不同的线程可以存取内存中的同一个变量。所以,程序中的转载 2012-10-19 11:05:56 · 482 阅读 · 0 评论 -
关于分离线程 .
线程的分离状态决定一个线程以什么样的方式来终止自己。线程的默认属性,一般是非分离状态,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。而分离线程没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态。 关于分离线程转载 2012-10-17 20:09:40 · 433 阅读 · 0 评论 -
编译性语言和解释性语言
首先,编程语言的发展过程:机器语言-->汇编语言-->高级语言。(C,Python同属于高级语言)机算机不能理解高级语言,只能理解机器语言,所以必须把高级语言翻译成机器语言,才能由计算机执行。翻译有两种方式:一种是编译;一种是解释。二者翻译时机不同。编译性语言:将源代码编译成机器语言文件,也即可执行程序。解释性语言:程序执行时将源代码翻译成机器语言,然后再由计算机执行。(也即将编译转载 2012-10-15 15:26:39 · 519 阅读 · 0 评论 -
shell执行过程
回车之后会发生什么? shell解释你的命令行 shell执行一些替换 shell在内存中装载你的命令 shell建立I/O的重定向 shell执行你的命令程序 shell等待你程序执行结束 shell等待下一条命令 当用户输入命令按回车之后,shell在执行命令之前会先解释该命令。当shell执行脚本文件时也是相同的顺序。 命令执行的次序是相当重要的。如果你违转载 2012-10-15 16:02:14 · 598 阅读 · 0 评论 -
软链接、硬链接
概念硬链接:也叫链接,即文件的引用,与被引用文件指向同一个Inode。例如,文件系统目录树上存在一个文件,该文件指向一个唯一的Inode,为该文件创建一个硬链接的话,那么该硬链接也指向同一个Inode,相当于该文件有两个名字,同时文件链接数增加1,可以使用任意一个名字访问该文件。软链接:也叫符号链接,即文件的快捷方式。软链接也是一种文件,同样占有一个Inode,创建软链接不增加链接数.转载 2012-10-15 15:37:45 · 521 阅读 · 0 评论 -
进程的阻塞和挂起的区别(整理)
理解一:挂起是一种主动行为,因此恢复也应该要主动完成,而阻塞则是一种被动行为,是在等待事件或资源时任务的表现,你不知道他什么时候被阻塞(pend),也就不能确切的知道他什么时候恢复阻塞。而且挂起队列在操作系统里可以看成一个,而阻塞队列则是不同的事件或资源(如信号量)就有自己的队列。理解二:阻塞(pend)就是任务释放CPU,其他任务可以运行,一般在等待某种资源或信号量的时候出现。挂起(suspen转载 2012-09-25 09:55:05 · 984 阅读 · 0 评论 -
unix解释器原理 .
转自: http://www.cnblogs.com/hbt19860104/archive/2008/07/24/1250898.html 引言使用Shell进行工作的人们对Unix/Linux下的Shell编程都很熟悉,在所有的Shell编程的书中都会提到#!/bin/bash,而这里到底包含了些什么?对操作系统而言,这一行字符串意味着什么?你可能会说,不就是会让 /bin/bas转载 2012-10-15 11:31:07 · 588 阅读 · 0 评论 -
《UNIX环境高级编程》学习之——更改用户ID组ID
UNIX系统为了总是以最小特权去执行一个程序,给出了setuid和setgid函数原型如下:#includeint setuid(uid_t uid);int setgid(gid_t gid);用户ID和组ID的更改规则是相通的,大家可以举一反三,下面写的都是关于用户ID的,组ID一样的原理。一个进程有自己的 实际用户ID(谁的程序)转载 2012-10-15 11:02:45 · 695 阅读 · 0 评论 -
POSIX 线程详解,第 3 部分---条件变量
条件变量详解在 上一篇文章结束时,我描述了一个比较特殊的难题:如果线程正在等待某个特定条件发生,它应该如何处理这种情况?它可以重复对互斥对象锁定和解锁,每次都会检查共享数据结构,以查找某个值。但这是在浪费时间和资源,而且这种繁忙查询的效率非常低。解决这个问题的最佳方法是使用 pthread_cond_wait() 调用来等待特殊条件发生。 了解 pthread_cond_wait()转载 2012-10-19 11:08:42 · 483 阅读 · 0 评论 -
POSIX 线程详解第 2部分--互斥量
在 前一篇文章中 ,谈到了会导致异常结果的线程代码。两个线程分别对同一个全局变量进行了二十次加一。变量的值最后应该是 40,但最终值却是 21。这是怎么回事呢?因为一个线程不停地“取消”了另一个线程执行的加一操作,所以产生这个问题。现在让我们来查看改正后的代码,它使用 互斥对象(mutex)来解决该问题:thread3.c#include #include转载 2012-10-19 11:07:39 · 9611 阅读 · 0 评论 -
多线程--条件变量
这次学习和互斥锁一起应用的cond--条件变量1.互斥锁的存在问题:互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定。设想一种简单情景:多个线程访问同一个共享资源时,并不知道何时应该使用共享资源,如果在临界区里加入判断语句,或者可以有效,但一来效率不高,二来复杂环境下就难以编写了,这是我们需要一个结构,能在条件成立时触发相应线程,进行变量修改和访问。2.条件变量:条件变量通过允许转载 2012-10-19 20:26:15 · 764 阅读 · 0 评论 -
linux下内存管理学习心得(二)
接着上面的知识,这篇主要总结如下几个方面知识:1、物理地址的页、区等概念2、内核使用内存的函数3、分配字节与分配页一、区、页前面linux下内存管理学习心得(一)也已经说了关于页的概念,在内核下面是把物理页(页框)作为分配的基本单元,内核下使用struct page结构体来表示系统中的物理页其中该结构体表示页是否被锁定在内存中,是否为脏页,该页被引用几次,同时还有页的虚原创 2013-03-19 15:43:36 · 1295 阅读 · 0 评论 -
linux下内存管理学习心得(一)
最近在学习内存管理的时候,发现对linux下的所谓内存如何管理如何分配都不熟悉,通过最近的查阅资料可总结如下,如有不妥之处欢迎大家批评与指正。总的的来说linux的内存管理其实主要难理解的是以下几个部分:1、虚拟地址、物理地址、线性地址、逻辑地址之间的区别。2、用户地址空间与内核地址空间区别。3、内核如何分配所谓的地址。4、一个可执行程序的地址分布以及运行地址分配。目前我也原创 2013-03-19 10:42:32 · 2899 阅读 · 0 评论 -
getopt
getopt被用来解析命令行选项参数。#include extern char *optarg; //选项的参数指针 extern int optind, //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。 extern int opterr, //当opterr=0时,getopt不向stderr输出转载 2012-12-14 10:21:50 · 400 阅读 · 0 评论 -
信号的接受
实现代码如下:#include #include #include void new_op(int,siginfo_t*,void*);//处理函数int main(int argc,char**argv){ struct sigaction act; int sig; sig=atoi(argv[1]);//将字符串转化为整型 sigemptyse原创 2012-10-26 16:05:28 · 590 阅读 · 0 评论 -
有名管道读写代码
一、读代码:#include #include #include #include #include #include #include #define FIFOTMP "./fifotmp"#define MAXLINE 1024int main(int argc,int *argv[]){ int fd; char buf[MAXLI原创 2012-10-26 09:22:15 · 2007 阅读 · 0 评论 -
IO的学习笔记 - 同步,异步,阻塞,非阻塞
总结下自己的学习心得: 一. 网络IO都必须经历的两个阶段: 对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。当一个read操作发生时,它会经历两个阶段: 1 等待数据准备 (Waiting for the data to转载 2012-10-23 20:28:01 · 447 阅读 · 0 评论 -
记录锁详解
子进程不继承父进程的记录锁.当可能出现几个进程争用(读、写)同一个Critical Section的时候,加锁是常用的做法。Linux加锁的方法,除了经典的IPC(Semophore)之外,记录锁(Record Locking)提供了更简单的方法。其实记录锁的名字叫文件锁会比较贴切一点,因为其加锁和解锁都是通过对文件的操作完成的。文件锁的粒度大可到整个文件,小可到一个字节,长度可变原创 2012-10-23 20:26:07 · 514 阅读 · 0 评论 -
pthread_cond_wait()用法分析
很久没看APUE,今天一位朋友问道关于一个mutex的问题,又翻到了以前讨论过的东西,为了不让自己忘记,把曾经的东西总结一下。先大体看下网上很多地方都有的关于pthread_cond_wait()的说明: 条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件转载 2012-10-19 21:33:10 · 626 阅读 · 0 评论 -
僵死进程
Unix: 僵死(Zombie)进程 进程在它的生命周期有几种状态:睡眠,可运行,停止,正在运行和僵死状态。所谓僵死进程,指的是一个进程已经退出,它的内存和相关的资源已经被内核释放 掉,但是在进程表中这个进程项(entry)还保留着,以便它的父进程得到它的退出状态。一个进程退出时,它的父进程会收到一个SIGCHLD信号。一般 情况下,这个信号的句柄通常执行wait系统调用,这转载 2012-10-15 08:49:07 · 563 阅读 · 0 评论 -
信号的未决 阻塞 .
信号的“未决”是一种状态,指的是从信号的产生到信号被处理前的这一段时间;可以通过 int sigpending (sigset_t *set) 和 int sigismember (const sigset_t *set, int signum) 查看某个信号是未决的。 信号的“阻塞”是一个开关动作,指的是阻止信号被处理,但不是阻止信号产生。 信号的阻塞就是让系统暂时保留信号转载 2012-09-24 09:06:13 · 394 阅读 · 0 评论 -
UNIX环境高级编程之信号
1、信号本质与来源信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可转载 2012-09-23 22:25:07 · 1958 阅读 · 2 评论 -
fork函数的写时拷贝
fork函数用于创建子进程,典型的调用一次,返回两次的函数,其中返回子进程的PID和0,其中调用进程返回了子进程的PID,而子进程则返回了0,这是一个比较有意思的函数,但是两个进程的执行顺序是不定的。fork函数调用完成以后父进程的虚拟存储空间被拷贝给了子进程的虚拟存储空间,因此也就实现了共享文件等操作。但是虚拟的存储空间映射到物理存储空间的过程中采用了写时拷贝技术(具体的操作大小是按着页控制的)转载 2012-10-14 21:33:49 · 633 阅读 · 0 评论 -
会话、进程组、进程个人理解
(1)进程必定属于一个进程组,也只能属于一个进程组。 一个进程组中可以包含多个进程。 进程组的生命周期从被创建开始,到其内所有进程终止或离开该组。 获取当前进程所在进程组ID使用函数getpgrp 创建或加入其他组使用函数setpgid(2)假设条件:pid1进程属于pgid1进程组;pid2属于pgid2进程组,并且是pgid2进程组组转载 2012-09-21 11:00:17 · 471 阅读 · 0 评论 -
进程组,会话,作业
终端的问题涉及几个概念,那就是进程组,会话,作业,下面会分别进行介绍。会话包含了一系列的进程,这些进程按照不同的执行内容会组织成若干进程组,一个会话内的所有进程都必须是该会话首长进程的后代,这样就保证了这些进程都是由该会话首长进程直接或者间接开启的,只有这样的才能保证这些进程确实是在会话首长进程耳目视线之内的,同时,孤儿进程组不再受到会话首长进程的控制。作业:只有一个终端,但是有很多事情要转载 2012-09-21 20:19:22 · 884 阅读 · 0 评论 -
UNIX文件系统概述
UNIX文件系统是UNIX系统的心脏部分,提供了层次结构的目录和文件。文件系统将磁盘空间划分为每1024个字节一组,称为块(block)(也有用512字节为一块的,如:SCO XENIX)。编号从0到整个磁盘的最大块数。 全部块可划分为四个部分,块0称为引导块,文件系统不用该块;块1称为专用块,专用块含有许多信息,其中有磁盘大小和全部块的其它两部分的大小。从块2开始是i节点表,i节点表中转载 2012-10-10 21:25:37 · 934 阅读 · 0 评论 -
有效用户ID、实际用户ID
实际用户ID,有效用户ID和设置用户ID 看UNIX相关的书时经常能遇到这几个概念,但一直没有好好去理清这几个概念,以致对这几个概念一直一知半解。今天好好区分了一下这几个概念并总结如下。说白了这几个UID引出都是为了系统的权限管理。 下面分别用RUID, EUID,SUID来表示实际用户ID,有效用户ID,设置用户ID。另外用户ID是个整型数,为了说明方便真接使用了转载 2012-09-19 11:33:32 · 896 阅读 · 0 评论 -
实际用户ID,有效用户ID,保存-设置-用户ID
如果当前进程具有超级权限则:调用setuid(uid)时,该进程可以将自己的:实际用户id,有效用户id,保存的set-user-id设置成其参数uid的值。既是说,特权用户进程可以将自己改变成任意进程。如果当前进程是非特权用户则:调用setuid(uid)时,如果uid是其实际用户id或保存的set-user-id,就把有效用户id设置成uid的值;如果uid不等于这两个值则将e转载 2012-09-19 14:40:50 · 876 阅读 · 0 评论 -
线程属性(1)
一.线程属性 线程具有属性,用pthread_attr_t表示,在对该结构进行处理之前必须进行初始化,在使用后需要对其去除初始化。我们用pthread_attr_init函数对其初始化,用pthread_attr_destroy对其去除初始化。 名称::pthread_attr_init/pthread_attr_destroy转载 2012-09-28 16:10:42 · 430 阅读 · 0 评论 -
可重入和不可重入
这种情况出现在多任务系统当中,在任务执行期间捕捉到信号并对其进行处理时,进程正在执行的指令序列就被信号处理程序临时中断。如果从信号处理程序返回,则继续执行进程断点处的正常指令序列,从重新恢复到断点重新执行的过程中,函数所依赖的环境没有发生改变,就说这个函数是可重入的,反之就是不可重入的。众所周知,在进程中断期间,系统会保存和恢复进程的上下文,然而恢复的上下文仅限于返回地址,cpu寄存器等之类的转载 2012-09-23 22:43:40 · 447 阅读 · 0 评论 -
dup 与 dup2
1. 文件描述符在内核中数据结构 一个进程在此存在期间,会有一些文件被打开,从而会返回一些文件描述符,从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2), 0与进程的标准输入相关联,1与进程的标准输出相关联,2与进程的标准错误输出相关联,一个进程当前有哪些打开的文件描述符可以通过/proc/进程ID/fd目录查看。 下图可以清楚的说明问题: 进程转载 2012-09-23 22:45:36 · 387 阅读 · 0 评论 -
深入fork
#include #include int main(void){ int i = 0; pid_t pid; printf("share ostream...."); for (i = 0; i <2; i++) { if ((pid = fork()) < 0) { printf("forkerror\n"转载 2012-09-23 22:47:03 · 360 阅读 · 0 评论 -
fork vfork .
vfork用于创建一个新进程,而该新进程的目的是exec一个新程序。vfork与fork一样都创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec(或exit),于是也就不会存访该地址空间。不过在子进程调用exec或exit之前,它在父进程的空间中运行。这种工作方式在某些UNIX的页式虚存实现中提高了效率(与上节中提及的,在fork之后跟随exec,并采用在转载 2012-09-24 08:51:18 · 568 阅读 · 0 评论 -
非局部跳转函数 setjmp 和 longjmp .
1. 非局部跳转函数 - setjmp 和 longjmp 函数 非局部指的是,这不是由普通C语言goto语句在一个函数内实施的跳转,而是在栈上跳过若干调用帧, 返回到当前函数调用路径上的某一个函数中。(简单点基本这样说:goto 语句用于同一个函数内跳转, 而 setjmp 和 longjmp的组合,不但可以实现函数内跳转,还可以实现函数间跳转) 特别注转载 2012-09-23 22:56:43 · 459 阅读 · 0 评论 -
如果依赖的库文件是由低版本gcc编译的怎么办 .
除了安装低版本的gcc外。可以在/usr/lib中添加对应的libstdc++.so.5试试。有时候它会自动创建libstdc++.so.6文件,所以在make之前要保证libstdc++.so.6没有在/usr/lib里。PS:使用ldconfig会自动创建libstdc++.so.6libstdc++.so.5下载地址:http://ishare.iask.sina.com.c转载 2012-09-23 22:54:45 · 784 阅读 · 0 评论 -
字符串转时间(time_t)
#include #include /** * str为日期字符串 * formatStr 为时间对应的格式, * 如2012-07-04 15:33:52对应的格式为%d-%d-%d %d:%d:%d */time_t string2time(const char * str,const char * formatStr){ s转载 2012-09-23 22:53:50 · 1954 阅读 · 0 评论 -
口令文件 getpwent()
#include #include struct passwd *getpwuid(uid_t uid);struct passwd *getpwnam(const char *name);#include #include #include #include struct passwd * getpwnam(const char *name){ stru转载 2012-09-23 22:53:04 · 512 阅读 · 0 评论 -
创建临时文件 tmpnam tmpfile tempnam mkstemp unlink
推荐使用 tmpfile mkstemp#include #include #include #include intmain(void){ FILE *pfile,*pfile2; int fileSize, readSize; char * fileBuff = NULL; char buff[128] = { 0 };/*****转载 2012-09-23 22:52:08 · 577 阅读 · 0 评论 -
时间相关 time() ctime time_t localtime() gettimeofday
1)求 时间差(精确到微秒) int gettimeofday (struct timeval *__restrict __tv,__timezone_ptr_t __tz);#include #include intmain(void){ int i=0; struct timeval tv,tv2; gettimeofday(&tv, NULL);转载 2012-09-23 22:50:30 · 999 阅读 · 0 评论