前言
本专栏是Linux系统编程学习笔记,内容主要是Linux的认识,命令,进程,IPC,信号,文件和多线程等,点击标题可进行跳转
第一部分
:主要是该篇博客涉及到的核心知识点
第二部分
:Linux系统编程中会涉及到大量系统调用,所以会以思维导图的方式总结
第三部分
:将博客中重要的代码操作拿出来,方便复习,练习
第一部分:博客知识点
(1)基础篇
此篇博客的内容较为简单,但是很重要——如何在Linux中安装软件,需要大家掌握yum的一些常用用法
(2)入门篇
(3)进程入门
第二部分:涉及的系统调用命令总结
(1)进程部分
(2)基础IO部分
(3)进程间通信部分
(4)进程信号部分
(5)多线程部分
第三部分:重要代码
1:理解fork的作用
#include <stdio.h>
#include <unistd.h>
int main ( )
{
prinf ( "还没有执行fork函数的本进程为:%d\n" , getpid ( ) ) ;
pid_t= fork ( ) ;
sleep ( 1 ) ;
if ( ret> 0 )
{
while ( 1 )
{
printf ( "----------------------------------------------------------------\n" ) ;
printf ( "我是父进程,我的id是:%d,我的孩子id是%d\n" , getpid ( ) , ret) ;
sleep ( 1 ) ;
}
}
else if ( ret== 0 )
{
while ( 1 )
{
printf ( "我是子进程,我的id是%d,我的父亲id是%d\n" , getpid ( ) , getppid ( ) ) ;
sleep ( 1 ) ;
}
}
else
printf ( "进程创建失败\n" ) ;
sleep ( 1 ) ;
return 0 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
2:理解僵尸状态
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main ( )
{
pid_t ret= fork ( ) ;
sleep ( 1 ) ;
if ( ret> 0 )
{
while ( 1 )
{
printf ( "----------------------------------------------------\n" ) ;
printf ( "父进程一直在运行\n" ) ;
sleep ( 1 ) ;
}
}
else if ( ret== 0 )
{
int count= 0 ;
while ( count<= 10 )
{
printf ( "子进程已经运行了%d秒\n" , count+ = 1 ) ;
sleep ( 1 ) ;
}
exit ( 0 ) ;
}
else
printf ( "进程创建失败\n" ) ;
sleep ( 1 ) ;
return 0 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
3:理解进程等待及waitpid第二个参数
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main ( )
{
pid_t ret= fork ( ) ;
sleep ( 1 ) ;
if ( ret> 0 )
{
printf ( "父进程正在等待子进程死亡\n" ) ;
int st= 0 ;
pid_t rec= waitpid ( ret, & st, 0 ) ;
if ( rec== ret)
{
printf ( "等待成功\n" ) ;
if ( WIFEXITED ( st) )
{
printf ( "正常退出且退出码为%d\n" , WEXITSTATUS ( st) ) ;
}
else
{
printf ( "异常退出,信号值为%d\n" , st& 0x7f ) ;
}
}
else
{
printf ( "等待失败\n" ) ;
exit ( 0 ) ;
}
}
else if ( ret== 0 )
{
int count= 1 ;
while ( count<= 10 )
{
printf ( "子进程[%d]已经运行了%d秒\n" , getpid ( ) , count) ;
count++ ;
sleep ( 1 ) ;
}
exit ( 3 ) ;
}
else
printf ( "进程创建失败\n" ) ;
sleep ( 1 ) ;
return 0 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
4:理解进程程序替换
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main ( )
{
int count= 0 ;
while ( count< 5 )
{
printf ( "Hello World\n" ) ;
sleep ( 1 ) ;
count++ ;
}
printf ( "%s\n" , getenv ( "myenv" ) ) ;
return 0 ;
}
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main ( )
{
char * env[ ] = { "myenv=you_can_see_this_env" , NULL } ;
printf ( "替换函数前\n" ) ;
execle ( "./myprocess.exe" , "myprocess.exe" , NULL , env) ;
printf ( "替换函数后\n" ) ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
5:理解文件描述符
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main ( )
{
int fd1= open ( "log1.txt" , O_WRONLY) ;
int fd2= open ( "log2.txt" , O_WRONLY| O_CREAT) ;
int fd3= open ( "log3.txt" , O_WRONLY| O_CREAT) ;
int fd4= open ( "log4.txt" , O_WRONLY| O_CREAT) ;
int fd5= open ( "log5.txt" , O_WRONLY) ;
printf ( "%d\n" , fd1) ;
printf ( "%d\n" , fd2) ;
printf ( "%d\n" , fd3) ;
printf ( "%d\n" , fd4) ;
printf ( "%d\n" , fd5) ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
6:理解匿名管道
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main ( )
{
int pipefd[ 2 ] = { 0 } ;
pipe ( pipefd) ;
pid_t id= fork ( ) ;
if ( id== 0 )
{
close ( pipefd[ 0 ] ) ;
const char * msg= "This is the data that the child process wrote" ;
while ( 1 )
{
write ( pipefd[ 1 ] , msg, strlen ( msg) ) ;
sleep ( 1 ) ;
}
}
else
{
close ( pipefd[ 1 ] ) ;
char buffer[ 64 ] ;
while ( 1 )
{
ssize_t ret= read ( pipefd[ 0 ] , buffer, sizeof ( buffer) - 1 ) ;
if ( ret> 0 )
{
buffer[ ret] = '\0' ;
printf ( "The father process got the information:%s\n" , buffer) ;
}
}
}
return 0 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
7:理解命名管道
server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main ( )
{
umask ( 0 ) ;
if ( mkfifo ( "./fifo" , 0666 ) == - 1 )
{
perror ( "打开失败" ) ;
return 1 ;
}
int fd= open ( "fifo" , O_RDONLY) ;
if ( fd>= 0 )
{
char buffer[ 64 ] ;
while ( 1 )
{
printf ( "客户端正在接受消息\n" ) ;
printf ( "############################\n" ) ;
ssize_t ret= read ( fd, buffer, sizeof ( buffer) - 1 ) ;
if ( ret> 0 )
{
buffer[ ret] = '\0' ;
printf ( "服务端接受到客户端消息:%s\n" , buffer) ;
}
else if ( ret== 0 )
{
printf ( "客户端已经下线,服务端下线\n" ) ;
break ;
}
else
{
perror ( "读取失败\n" ) ;
break ;
}
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
client.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main ( )
{
int fd= open ( "fifo" , O_WRONLY) ;
if ( fd>= 0 )
{
char buffer[ 64 ] ;
while ( 1 )
{
printf ( "客户端-请输入消息:" ) ;
ssize_t ret= read ( 0 , buffer, sizeof ( buffer) - 1 ) ;
if ( ret> 0 )
{
buffer[ ret] = '\0' ;
write ( fd, buffer, ret) ;
}
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
8:理解共享内存
server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/shm.h>
#define PATHNAME "tmp"
#define PROJ_ID 88
#define SIZE 4096
int main ( )
{
key_t k= ftok ( PATHNAME, PROJ_ID) ;
printf ( "key值:%#X\n" , k) ;
int shmid= shmget ( k, SIZE, IPC_CREAT | IPC_EXCL| 0666 ) ;
if ( shmid< 0 )
{
perror ( "creat failed" ) ;
return 1 ;
}
char * shmaddr= shmat ( shmid, NULL , 0 ) ;
while ( 1 )
{
sleep ( 1 ) ;
printf ( "%s\n" , shmaddr) ;
}
shmdt ( shmaddr) ;
shmctl ( shmid, IPC_RMID, NULL ) ;
return 0 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/shm.h>
#define PATHNAME "tmp"
#define PROJ_ID 88
#define SIZE 4096
int main ( )
{
key_t k= ftok ( PATHNAME, PROJ_ID) ;
printf ( "key值:%#X\n" , k) ;
int shmid= shmget ( k, SIZE, 0 ) ;
if ( shmid< 0 )
{
perror ( "creat failed" ) ;
return 1 ;
}
char * shmaddr= shmat ( shmid, NULL , 0 ) ;
int i= 0 ;
while ( i< 26 )
{
shmaddr[ i] = 97 + i; 每隔5 s依次输入a, b, c. . . . . . . . . . . . . . . . . . . . . . . . . . .
i++ ;
sleep ( 5 ) ;
}
shmdt ( shmaddr) ;
return 0 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
9:理解signal函数
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void handler ( int sig)
{
printf ( "catch a sin : %d\n" , sig) ;
}
int main ( )
{
signal ( 2 , handler) ;
while ( 1 )
{
printf ( "I Am runnng now...\n" ) ;
sleep ( 1 ) ;
}
return 0 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
10:理解信号集操作函数
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void handler ( int sig)
{
printf ( "获得信号:%d\n" , sig) ;
}
void print_pending ( sigset_t* pending)
{
int i= 1 ;
for ( i= 1 ; i<= 31 ; i++ )
{
if ( sigismember ( pending, i) )
{
printf ( "1" ) ;
}
else
{
printf ( "0" ) ;
}
}
printf ( "\n" ) ;
}
int main ( )
{
signal ( 2 , handler) ;
sigset_t pending;
sigset_t block, oblock;
sigemptyset ( & block) ;
sigemptyset ( & oblock) ;
sigaddset ( & block, 2 ) ;
sigprocmask ( SIG_SETMASK, & block, & oblock) ;
int cout= 0 ;
while ( 1 )
{
sigemptyset ( & pending) ;
sigpending ( & pending) ;
print_pending ( & pending) ;
sleep ( 1 ) ;
cout++ ;
if ( cout== 10 )
{
printf ( "解除阻塞\n" ) ;
sigprocmask ( SIG_SETMASK, & oblock, NULL ) ;
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
11:理解线程的创建,等待等
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void * new_thread ( void * arg)
{
while ( 1 )
{
printf ( "我是新线程,我的线程id是%p\n" , pthread_self ( ) ) ;
sleep ( 5 ) ;
int a= 1 / 0 ;
}
}
int main ( )
{
pthread_t tid;
pthread_create ( & tid, NULL , new_thread, ( void * ) "我是新线程" ) ;
while ( 1 )
{
printf ( "-----------------------------------------------------------\n" ) ;
printf ( "我是主线程,我的线程id是:%p,新线程的id是%p\n" , pthread_self ( ) , tid) ;
void * ret;
pthread_join ( tid, & ret) ;
printf ( "主线程阻塞等待新线程,退出码码为%d\n" , ( int ) ret) ;
break ;
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
12:理解互斥锁
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int tickets= 1000 ;
pthread_mutex_t lock;
void scarmble_tickets ( void * arg)
{
long int ID= ( long int ) arg;
while ( 1 )
{
pthread_mutex_lock ( & lock) ;
if ( tickets> 0 )
{
usleep ( 1000 ) ;
printf ( "线程%ld号抢到了一张票,现在还有%d张票\n" , ID, tickets) ;
tickets-- ;
pthread_mutex_unlock ( & lock) ;
}
else
{
pthread_mutex_unlock ( & lock) ;
break ;
}
}
}
int main ( )
{
int i= 0 ;
pthread_t tid[ 4 ] ;
pthread_mutex_init ( & lock, NULL ) ;
for ( i= 0 ; i< 4 ; i++ )
{
pthread_create ( tid+ 1 , NULL , scarmble_tickets, ( void * ) i) ;
}
for ( i= 0 ; i< 4 ; i++ )
{
pthread_join ( tid+ 1 , NULL ) ;
}
pthread_mutex_destroy ( & lock) ;
return 0 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
13:理解条件变量
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
pthread_mutex_t lock;
pthread_cond_t cond;
void * thread_a ( void * arg)
{
const char * name= ( char * ) arg;
while ( 1 )
{
pthread_cond_wait ( & cond, & lock) ;
printf ( "%s被唤醒了\n=================================================\n" , name) ;
}
}
void * thread_1 ( void * arg)
{
const char * name= ( char * ) arg;
while ( 1 )
{
sleep ( rand ( ) % 5 + 1 ) ;
pthread_cond_signal ( & cond) ;
printf ( "%s现在正在发送信号\n" , name) ;
}
}
int main ( )
{
pthread_mutex_init ( & lock, NULL ) ;
pthread_cond_init ( & cond, NULL ) ;
pthread_t t1, t2, t3, t4, t5;
pthread_create ( & t1, NULL , thread_1, ( void * ) "线程1" ) ;
pthread_create ( & t2, NULL , thread_a, ( void * ) "线程2" ) ;
pthread_create ( & t3, NULL , thread_a, ( void * ) "线程3" ) ;
pthread_create ( & t4, NULL , thread_a, ( void * ) "线程4" ) ;
pthread_create ( & t5, NULL , thread_a, ( void * ) "线程5" ) ;
pthread_join ( t1, NULL ) ;
pthread_join ( t2, NULL ) ;
pthread_join ( t3, NULL ) ;
pthread_join ( t4, NULL ) ;
pthread_join ( t5, NULL ) ;
pthread_mutex_destroy ( & lock) ;
pthread_cond_destroy ( & cond) ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
14:生产者与消费者模型
Linux系统编程39:多线程之基于阻塞队列生产者与消费者模型
Linux系统编程40:多线程之基于环形队列的生产者与消费者模型
15:理解线程池
上。