Linux Programming

1、Linux基本语法

1.1 make命令

make 命令执行 make target 格式 eg make clean 执行rm -f *.omake test 执行gcc test.o pro1.o pro2.o -o test

1.2 lib库函数

关于 gcc中 调用math.h中的函数 gcc -c -o 遇到的问题 eg gcc math_demo1.c -o math_demo1 -lm 要加lm 其中 lm为libmath的简称 在gcc -o 生成lib的时候的命名时 为libxx简称为lx eg libmath简称lm

1.3 一些函数

1.3.1 chmod

S_IRUSR 所有者具有读取权限 S_IWUSR 所有者具有写权限 S_XUSR 所有者具有执行权限
USR usr所有者 GRP group组 OTH 用户 R读 W写 X执行

1.3.2 open create

O_RDONLY 以只读模式打开 O_WRONLY 以写入模式打开 O_RDWR 以读写模式打开 O_APPEND 在文件尾写入数据

O_TRUNG 设置文件的长度为0 并且舍弃现存的数据 O_CREAT 建立文件 使用mode参数设置访问权限 O_EXCL 与O_CREAT一起使用

1.3.3 fcntl文件锁

1、fcntl文件上锁 避免共享的资源产生竞争,导致数据读写发生错误。 当一个文件被加上强制锁之后,内核将阻止其他任何文件对器进行读写操作

flock结构体 p192 Linux程序设计第二版 flock函数用于锁定文件或者解除锁定 关于flock和fcntl函数的说明p193

2、fopen函数 带缓冲的文件I/O操作 p194 fgets函数在p199 用户从文件中读取一字符串

2、 进程控制

2.1 进程简介

1、进程 有手工启动和调度启动两种 at命令 用于在未来某个时间执行某个任务
exec函数 在进程中启动另一个程序执行 exelc有6个函数来建立子进程 分别是execl execv execle execve execlp execvp

2、fork函数从已存在的进程中复制一个新进程 waitpid暂停父进程 等待子进程运行完成
为了执行一个程序 需要一种机制使子进程成为要执行的命令 Linux系统调用exec完成这项工作,进程可以用另外一个程序的可执行代码来覆盖自身。

2.2 僵尸进程

1、僵尸进程 p229 一个已经终止运行 但其父进程尚未对其进行善后处理 eg释放他占用的资源
fork函数创建子进程后,由于子进程有可能比父进程晚终止 ,即父进程终止后,子进程没有终止 可以在父进程调用wait 或 waitpid函数
wait函数的作用是使父进程阻塞,直到一个子进程终止或者该进程接到来一个指定的信号为止。waitpid和wait函数的作用相同,但其不一定要等待第一个子进程终止

2.3 守护进程

2.3.1 守护进程

守护进程 daemon p239 是运行在后台,并且一直在运行的特殊进程 独立于控制终端并且周期性执行某种任务或者等待处理某些发生的时间。守护进程是一个很有用的进程,Linux绝大多数的服务器就是用守护进程实现的,比如作业控制进程crond,web服务器httpd,internet服务器inetd等等.
守护进程必须要与其他运行钱的环境隔离开来,这些环境包括未关闭的文件描述符,控制终端,会话等。

2.3.2 守护进程的编写

1、创建子进程 终止父进程
创建子进程 终止父进程 ,由于守护进程是脱离控制终端的,因此首先创建子进程,终止父进程,造成一个已经运行完毕的假象。
创建子进程,终止父进程的代码如下:

pid=fork();
if(pid>0){
    exit(0);//终止父进程
}

2、在子进程中创建新会话
这个步骤是创建守护进程中的最重要的一步,在这一步使用的是系统函数setsid,该函数用于创建一个新的会话,并且担任该会话组的组长。调用setsid函数有三个作用:让进程摆脱原会话的控制、让进程摆脱原进程组的控制和让进程摆脱原终端控制终端的作用。

​ 在调用fork函数时,子进程全盘拷贝之父进程的会话期session、进程组、控制终端等。setsid函数使得进程完全独立出来,从而脱离所有其他进程的控制。
3、改变工作目录
使用fork创建的子进程也继承来父进程的当前工作目录。由于在进程运行中,当前目录所在的文件系统不能卸载,因此,把当前工作目录换成其他路径 eg:/ 或/tmp 。改变工作目录常见的函数是chdir.
4、重设文件创建掩码
由于使用fork函数创建的新进程继承了父进程的文件创建掩码,这就给该子进程使用文件带来了诸多麻烦,因此,把文件创建掩码设置为0,可以大大增加该守护进程的灵活性。设置文件创建掩码的函数是umask.通常使用方法是为umask(0);
5、关闭文件描述符
用fork函数新建的子进程会从父进程那里继承一些已经打开来的文件,在这些被打开的文件可能永远不会被守护进程读写,但他们一样会消耗系统资源,可能导致所在的文件系统无法卸载。因此一般要关闭文件描述符:

for(i=0;i<NOFILE;i++)
    cloes(i);
//也可以按找如下方式
for(int i=0;i<MAXFILE;i++)
    cloes(i);

2.3.3 守护进程的一个demo

//初始化一个精灵进程
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
void daemonize(){
    pid_t pid;
    //调用fork创建新进程  返回值存在pid中 返回两个值  返回值为0代表子进程 返回值大于0代表父进程
    if((pid==fork())<0){
    	perror("fork failed");
    	exit(1);
    }
    else if(pid!=0){//父进程
        exit(0);  //创建子进程,终止父进程
    }
    //在子进程中创建一个新的对话
    setsid();
    //改变当前目录到 "/"
    chdir("/");
    //重设文件创建掩码
	umask(0); /* clear file mode creation mask */
    //关闭文件描述符
    for(i=0;i<NOFILE;i++)
    	cloes(i);
    
    //标准输入、标准输出、错误输出重定向到空设备  黑洞 /dev/null中
    open("/dev/null",O_RDWR);
    /*
    函数dup和dup2提供了复制文件描述符的功能
      输入重定向:关闭标准输入设备,打开(或复制)某普通文件,使其文件描述符为0.
   	  输出重定向:关闭标准输出设备,打开(或复制)某普通文件,使其文件描述符为1.
      错误输出重定向:关闭标准错误输入设备,打开(或复制)某普通文件,使其文件描述符为2.
     */
    dup2(0,1);
    dup2(0,2);
}

2.3.4 守护进程注意要点

按照守护进程的惯例,通常将当前工作目录切换到根目录,将文件描述符0,1,2 重定向到/dev/null
父进程创建来子进程,而父进程退出之后,此时该子进程变成来孤儿进程。在linux中,每当系统发现孤儿进程之后,signal就自动由1号进程(也就是init进程)收养他,原先的子进程就会变为init进程的子进程。

在linux系统中,程序变为守护进程之后,完全脱离来终端的控制,调试的时候也没法像普通程序那样调试,用gdb也无法正常调试。

因此,编写调试守护进程,一般是利用系统日志服务,通过系统守护进程syslogd控制自己编写的守护进程的告警信息。linux C语言中,只要调用syslog函数,将守护进程的出错信息写入”/var/log/message”系统日志文件中,就可以做到对守护进程的调试。

2.3.5 syslog函数介绍说明

其功能是将信息记录至系统日志文件 void syslog(int priority ,char *format,...);

其中priority指定信息的种类等级,主要有LOG_INFO 提示相关信息,LOG_DEBUG 出错信息,format参数和printf函数参数相同。

注意:调用openlog、syslog函数,操作的系统日志文件”/var/log/message”,必须要有root权限。

3、进程通信

3.1进程间通信

每个进程有各自的进程地址空间,任何一个进程的全局变量在另一个进程中都不能访问,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区。能实现进程间通信的方法有:信号signal、管道pipe、套接字socket和System V IPC机制(包括消息队列、信号量、共享内存)。

3.1.1 信号signal

信号可以在任何时候发给某个进程,而无需知道该进程的状态,如该进程当前处于未执行状态,则该信号内核保存起来,直到该进程恢复执行并传递给他为止。

​ Linux提供来十几种信号,信号之间依靠他们的值来区分,但是通常在程序中使用信号的名字来代表一个信号。通常程序中不需要直接包含/usr/include/bits/signum.h头文件,而是应该包含<signal.h>

3.1.2 Linux系统常见的信号的含义及其默认操作

信号名含义默认操作
SIGQUIT该信号在用户按下退出键(crtl+\),造成系统非正常终止终止
SIGKILL一个特殊信号,用来立即结束程序的运行,并且不能被阻塞,处理,或忽略终止
SIGTERM程序结束信号, 与SIGKILL不同的是该信号可以被阻塞和 处理. 通常用来要求程序自己正常退出.终止
SIGSTOP特殊信号,用于暂停一个进程,并且不能被阻塞,处理,或忽略暂停进程
SIGALRM该信号在一个定时器计时完成时发生,定时器可以用进程调用alarm函数来设置终止

3.1.3 信号操作的相关函数

函数功能
kill发送信号SIGKILL给进程或进程组
signal捕捉信号SIGINT 、SIG_IGN、SIG_QUIT时执行信号处理函数
alarm定时器时间到时,向进程发送SIGALARM信号

具体详细内容参见《Linux程序设计》p256-257

1、信号发送
kill函数用于给特定的进程发送信号,raies函数用于向某个进程自身发送信号。
2、信号处理

//主程序无限循环,用户按下ctrl+c发送信号SIGINT ,此时调用fun_ctrl_c处理函数,设置信号处理的函数是signal
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
void fun_ctrl_c(){//自定义信号处理函数
    printf("按下来ctrl+c");
	puts("有什么要处理的,在处理信号中编程");
    (void)signal(SIGINT,SIG_DFL);
}
int main(){
    (void)signal(SIGINT,fun_ctrl_c);//按下了ctrl+c 调用fun_ctrl_c函数
    printf("主程序,无限循环");
    while(1){
    }
    return 0;
}

3.2 管道

3.2.1 无名管道相关操作

pipe用于相关进程之间的通信,如父子进程,通过pipe()系统调用来创建并打开,最后一个进程关闭对他的引用时,pipe自动撤销。

管道的实质是一个内核缓冲区,进程可以以先进先出的方式从缓冲区中存取数据

无名管道的操作 见书p269页

char buf_r[100];
memset(buf_r,0sizeof(buf_r));//把buf_r所指的内存区域前sizeof(buf_r)得到的字节置为0,初始化清空

memset函数 将一段内存空间填入某值

3.2.2 高级管道相关操作

在linux c程序设计中,除了常用的pipe系统调用来建立管道外,还可以使用管道库函数popen函数来创建管道。

#include<stdio.h>
int main(){
    FILE *fp;
    int num;
    char buf[5000];
    memset(buf,0,sizeof(buf));//初始化清空操作
    puts("建立管道");
    fp=open("ls -l","r");//调用popen函数,建立管道(读管道)
    if(fp!=null){
        num=fread(buf,sizeof(char),5000,fp);
        if(num>0){
        	puts("命令为'ls -l',运行结果如下: ");
        	puts(buf);
        }
        pclose(fp);
    }
    else{
        puts("创建管道失败");
        return 1;
    }
    fp=popen("grep lm.c","w");//调用popen函数,建立管道(写管道
    puts("第二个命令 'grep lm.c' 运行结果如下")
	fprintf(fp,"%s\n",buf);
    pclose(fp);
    return 0;
}

popen函数相关介绍在p283,其中 FILE fopen(const char command,const char type),在编写具有SUID/SGID 权限的程序时,尽量避免使用popen(),因为popen()会继承环境变量。通过环境变量会造成系统安全问题。

3.3 消息队列

​ 消息队列就是一个消息的链表,是一系列保存在内核中的消息的列表。Linux采用消息队列的方式来实现消息传递,发送方可以不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果如果没有收到消息也不需要等待。新的消息总是在队列的末尾,接受的时候并不总是从同来接收,可以从中间接收。

3.4 共享内存

共享内存允许两个或多个进程共享一个给定的存储区,这一段存储区可以被两个或两个以上的进程映射至自身地址空间中。

​ 内存映射机制使进程之间通过映射同一个普通文件实现共享内存,通过mmap()系统调用来实现。普通文件被映射到地址空间后,进程可以像访问普通内存一样对文件进行访问,不必在调用read和write等文件操作。

注:linux程序设计暂时到这,其他的如多线程,网络编程等技术,暂时不用,到时候用的时候在更新。

本篇blog参考书籍为《linux程序设计第二版》金国庆、刘加海、季江民、严冰。

参考文档:
1、标准md语法教程
2、重定向编程 dup和dup2函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
xv Contents Graphical Debugging Tools 299 DDD 299 Eclipse 302 Kernel Debugging 305 Don’t Panic! 306 Making Sense of an oops 307 Using UML for Debugging 309 An Anecdotal Word 312 A Note about In-Kernel Debuggers 313 Summary 313 Chapter 11: The GNOME Developer Platform 315 GNOME Libraries 316 Glib 316 GObject 316 Cairo 316 GDK 317 Pango 317 GTK+ 317 libglade 318 GConf 318 GStreamer 318 Building a Music Player 319 Requirements 319 Getting Started: The Main Window 319 Building the GUI 321 Summary 340 Chapter 12: The FreeDesktop Project 341 D-BUS: The Desktop Bus 341 What Is D-Bus? 342 Under D-Hood of D-Bus 342 D-Bus Methods 346 Hardware Abstraction Layer 350 Making Hardware Just Work 350 Hal Device Objects 353 The Network Manager 358 Other Freedesktop Projects 360 Summary 360 02_776130 ftoc.qxp 2/2/07 10:13 PM Page xv xvi Contents Chapter 13: Graphics and Audio 361 Linux and Graphics 361 X Windows 362 Open Graphics Library 364 OpenGL Utilities Toolkit 365 Simple Directmedia Layer 365 Writing OpenGL Applications 365 Downloading and Installing 366 Programming Environment 367 Using the GLUT Library 368 Writing SDL Applications 382 Downloading and Installing 382 Programming Environment 383 Using the SDL Library 383 Summary 394 Chapter 14: LAMP 395 What Is LAMP? 395 Apache 396 MySQL 396 PHP 397 The Rebel Platform 397 Evaluating the LAMP Platform 397 Apache 399 Virtual Hosting 400 Installation and Configuration of PHP 5 401 Apache Basic Authentication 402 Apache and SSL 402 Integrating SSL with HTTP Authentication 403 MySQL 404 Installing MySQL 404 Configuring and Starting the Database 404 Changing the Default Password 405 The MySQL Client Interface 405 Relational Databases 405 SQL 406 The Relational Model 409 PHP 411 The PHP Language 411 Error Handling 420 Error-Handling Exceptions 421 02_776130 ftoc.qxp 2/2/07 10:13 PM Page xvi xvii Contents Optimization Techniques 422 Installing Additional PHP Software 427 Logging 427 Parameter Handling 428 Session Handling 429 Unit Testing 430 Databases and PHP 432 PHP Frameworks 432 The DVD Library 433 Version 1: The Developer’s Nightmare 433 Version 2: Basic Application with DB-Specific Data Layer 434 Version 3: Rewriting the Data Layer,Adding Logging and Exceptions 437 Version 4: Applying a Templating Framework 441 Summary 442 Index 443 GNU 47 Acknowledgments ix Introduction xix Chapter 1: Working with Linux 1 A Brief History of Linux 2 The GNU Project 2 The Linux Kernel 3 Linux Distributions 4 Free Software vs. Open Source 4 Beginning Development 5 Choosing a Linux Distribution 6 Installing a Linux Distribution 8 Linux Community 15 Linux User Groups 15 Mailing lists 16 IRC 16 Private Communities 16 Key Differences 16 Linux Is Modular 17 Linux Is Portable 17 Linux Is Generic 17 Summary 18 Chapter 2: Toolchains 19 The Linux Development Process 19 Working with Sources 20 Configuring to the Local Environment 21 Building the Sources 22 Components of the GNU Toolchain 23 The GNU Compiler Collection 23 The GNU binutils 34 GNU Make 39 The GNU Debugger 40 02_776130 ftoc.qxp 2/2/07 10:13 PM Page xi xii Contents The Linux Kernel and the GNU Toolchain 44 Inline Assembly 44 Attribute Tags 45 Custom Linker Scripts 45 Cross-Compilation 46 Building the GNU Toolchain 47 Summary 48 Chapter 3: Portability 49 The Need for Portability 50 The Portability of Linux 51 Layers of Abstraction 51 Linux Distributions 52 Building Packages 57 Portable Source Code 70 Internationalization 81 Hardware Portability 88 64-Bit Cleanliness 89 Endian Neutrality 89 Summary 92 Chapter 4: Software Configuration Management 93 The Need for SCM 94 Centralized vs. Decentralized Development 95 Centralized Tools 95 The Concurrent Version System 96 Subversion 104 Decentralized tools 108 Bazaar-NG 109 Linux kernel SCM (git) 112 Integrated SCM Tools 115 Eclipse 115 Summary 117 Chapter 5: Network Programming 119 Linux Socket Programming 119 Sockets 120 Network Addresses 122 Using Connection-Oriented Sockets 123 Using Connectionless Sockets 130 02_776130 ftoc.qxp 2/2/07 10:13 PM Page xii xiii Contents Moving Data 133 Datagrams vs. Streams 133 Marking Message Boundaries 137 Using Network Programming Libraries 140 The libCurl Library 140 Using the libCurl Library 141 Summary 147 Chapter 6: Databases 149 Persistent Data Storage 149 Using a Standard File 150 Using a Database 150 The Berkeley DB Package 152 Downloading and Installing 153 Building Programs 154 Basic Data Handling 154 The PostgreSQL Database Server 165 Downloading and Installing 165 Building Programs 167 Creating an Application Database 167 Connecting to the Server 169 Executing SQL Commands 173 Using Parameters 181 Summary 184 Chapter 7: Kernel Development 185 Starting Out 185 Kernel Concepts 199 A Word of Warning 200 The Task Abstraction 200 Virtual Memory 205 Don’t Panic! 208 Kernel Hacking 208 Loadable Modules 209 Kernel Development Process 211 Git: the “Stupid Content Tracker” 212 The Linux Kernel Mailing List 213 The “mm” Development Tree 215 The Stable Kernel Team 215 LWN: Linux Weekly News 216 Summary 216 02_776130 ftoc.qxp 2/2/07 10:13 PM Page xiii xiv Contents Chapter 8: Kernel Interfaces 217 What Is an Interface? 217 Undefined Interfaces 218 External Kernel Interfaces 219 System Calls 219 The Device File Abstraction 224 Kernel Events 238 Ignoring Kernel Protections 239 Internal Kernel Interfaces 243 The Kernel API 243 The kernel ABI 244 Summary 245 Chapter 9: Linux Kernel Modules 247 How Modules Work 247 Extending the Kernel Namespace 250 No Guaranteed Module Compatibility 251 Finding Good Documentation 251 Linux Kernel Man Pages 251 Writing Linux Kernel Modules 252 Before You Begin 253 Essential Module Requirements 253 Logging 256 Exported Symbols 257 Allocating Memory 259 Locking considerations 267 Deferring work 275 Further Reading 283 Distributing Linux Kernel Modules 284 Going Upstream 284 Shipping Sources 284 Shipping Prebuilt Modules 284 Summary 285 Chapter 10: Debugging 287 Debugging Overview 287 A Word about Memory Management 288 Essential Debugging Tools 289 The GNU Debugger 289 Valgrind 298 02_776130 ftoc.qxp 2/2/07 10:13 PM Page xiv
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值