有名管道:
目录
有名管道:
1.创建(mkfifo):
2。打开(open):
3.读写(read /write):
4.关闭(close):
5.卸载(remove):
练习:
(1)写文件
(2)读文件
附录:
信号:
1.发送端:
1.signal函数:
2.kill函数:
3.pause函数:
2.信号含义
3.接收端
练习:
mplayer:
有名管道===》fifo===》有文件名称的管道
1):存在于内存中;
2):在系统中有一个对应名称;
3):文件大小;0 bytes


1.创建(mkfifo):
int mkfifo(const char *pathname, mode_t mode);
(1)功能:在指定的pathname路径+名称下创建一个权限为mode的有名管道文件。
(2)参数:a)pathname:要创建的有名管道路径+名称;
b)mode 8进制文件权限。
(3)返回值:成功0;失败-1;
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        printf("Usage: %s <filename>\n",argv[0]);
        return -1;
    }
    if(mkfifo(argv[1], 0666) < 0 && errno != EEXIST)
    {
        perror("mkfifo fail");
        return -1;
    }
    printf("---mkfifo-success\n");
    return 0;
} 
2。打开(open):
int open(const char *pathname, int flags);
        因为管道是半双工模式,所有打开方式直接决定当前进程的读写方式。
          一般只有如下方式:
                 (1)int fd-read = open("./fifo",O_RDONLY); ==>fd 是固定读端
                 (2)int fd-write = open("./fifo",O_WRONLY); ==>fd 是固定写端
         不能是 O_RDWR 方式打开文件。
         不能有 O_CREAT 选项,因为创建管道有指定的mkfifo函数
3.读写(read /write):
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
4.关闭(close):
int close(int fd);
5.卸载(remove):
int remove(const char *pathname);
练习:
(1)写文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
	if (argc != 2)
	{
		printf("Usage: %s <filename>\n",argv[0]);
		return -1;
	}
	if (mkfifo(argv[1],0666) < 0 && errno != EEXIST)
	{
		perror("mkfifo fail");
		return -1;
	}
	printf("----mkfifo -- success\n");
	int fd = open(argv[1],O_WRONLY);
	if (fd < 0)
	{
		perror("open fail");
		return -1;
	}
	printf("----open success---\n");
	
	//从键盘输入数据 写到 管道中 
	char buf[1024];
	
	while (1)
	{
		fgets(buf,sizeof(buf),stdin);
		write(fd,buf,strlen(buf)+1);
		if (strncmp(buf,"quit",4) == 0)
		{
			remove(argv[1]);
			close(fd);
			break;
		}
	}
	return 0;
} 
(2)读文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
	if (argc != 2)
	{
		printf("Usage: %s <filename>\n",argv[0]);
		return -1;
	}
	if (mkfifo(argv[1],0666) < 0 && errno != EEXIST)
	{
		perror("mkfifo fail");
		return -1;
	}
	printf("----mkfifo -- success\n");
	int fd = open(argv[1],O_RDONLY);
	if (fd < 0)
	{
		perror("open fail");
		return -1;
	}
	printf("----open success---\n");
	
	//从管道中读数据 
	char buf[1024];
	while (1)
	{
		read(fd,buf,sizeof(buf));
		printf("buf = %s",buf);
		if (strncmp(buf,"quit",4) == 0)
		{
			remove(argv[1]);
			close(fd);
			break;
		}
	}
	return 0;
} 
附录:
-  
有名管道执行过程过必须有读写端同时存在。如果有一端没有打开,则默认在open函数部分阻塞。
 -  
可以在有亲缘关系的进程间使用。启动的次序可能会导致其中一个稍有阻塞。
 -  
手工操作有名管道实现数据的传送。读: cat fifoname;写: echo "asdfasdf" > fifoname
 
信号:
本身并不能传送大量数据(异步通信);
软中断(软件层面,对中断过程的一种模拟);

1.发送端:
1.signal函数:
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
(1)功能:信号处理函数的注册(安装)函数
(2)参数:a)signum:要处理的信号的编号(不能被阻塞,一般有三种:[SIG_IGN](忽略);[SIG_DEL](默认操作);自定义);
                            b) handler:对次信号作何处理(为一个指针,指向信号处理的函数。忽略[SIG_IGN]默认操作[SIG_DFL];
         (3)返回值:成功:上一次设置的信号处理函数的入口地址;失败:[SIG_ERR];
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sighandler(int signo)
{
    printf("****************d\n",signo);
}
int main(int argc, char *argv[])
{
  //  signal(SIGINT,SIG_IGN);
      signal(SIGINT,sighandler);
    while(1)
    {
        printf("-----hello-----world-----\n");
        sleep(1);
    }
    return 0;
} 
2.kill函数:
int kill(pid_t pid, int sig);
        (1)功能:通过该函数可以给pid进程发送信号为sig的系统信号。
         (2)参数:a)pid:要接收信号的进程pid;
                             b)sig:当前程序要发送的信号编号 《=== kill  -l
         (3)返回值:成功 0;失败  -1;
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sighandler(int signo)
{
    if(signo == 2)
        printf("hahahahahahahahahahahahahah%d\n",signo);
    else if(signo == 10)
        printf("hahahahahahahahahahahahahah%d\n",signo);
}
int main(int argc, char *argv[])
{
    signal(SIGINT,SIG_IGN);
    signal(SIGUSR1,sighandler);
    int i = 0;
    while(1)
    {
        printf("-----hello-----world-----\n");
        sleep(1);
        ++i;
        if(i % 3 == 0)
            kill(getpid(),SIGUSR1);
    }
    return 0;
} 
3.pause函数:
int pause(void);
(1)功能:进程暂停,不再继续执行,除非收到其他信号。
2.信号含义
kill-l自查
3.接收端
        每个进程都会对信号作出默认响应,但不是唯一响应。
         一般如下三种处理方式:
                         1、默认处理
                         2、忽略处理 9,19
                         3、自定义处理 9,19 捕获
练习:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
void sighandler(int signo)
{
    printf("wait child!\n");
    wait(NULL);
}
int main(int argc, char *argv[])
{
    signal(SIGCHLD,sighandler);
    pid_t pid = fork();
    if(pid < 0)
    {
        perror("fork fail\n");
        return -1;
    }
    if(pid > 0)
    {
        while(1)
        {
            printf("father pid = %d\n",getpid());
            sleep(1);
        }
    }else if(pid == 0)
    {
        int i = 0; 
        while(i < 5)
        {
            printf("child pid = %d\n",getpid());
            sleep(1);
            ++i;
        }
    }
    return 0;
} 
mplayer:
mplayer -slave -input file=./fifo 1.mp4
echo "stop" > fifo
echo "pause" > fifo
- 播放上一曲 下一曲 ;
 - 播放下一曲;
 - 关掉当前正在播放。 //就是关
 
正常播放 //播放模式 (顺序,单曲,随机)
    //mplayer --媒体文件 获取当前的长度 
    //fork一个子进程播 
    //SIGCHILD 信号 
    //直接播放下一曲 
附录(自定义):
自定义信号处理:
     1、必须事先定义自定义函数,必须是如下格式:   
  void fun(int sig)  sig 接收到的信息编号
        {
        } 
2、在所有的信号中有如下两个特列:10 【SIGUSR1】;12 【SIGUSR2】专门预留给程序员使用的未定义信号。
1)程序不可捕获、阻塞或忽略的信号有:SIGKILL,SIGSTOP
 2)不能恢复至默认动作的信号有:SIGILL,SIGTRAP
 3)默认会导致进程流产的信号有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ
 4)默认会导致进程退出的信号有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM
 5)默认会导致进程停止的信号有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU
 6)默认进程忽略的信号有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH
7)此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在进程挂起时是继续,否则是忽略,不能被阻塞。



















