Linux进程通信
2016-07-05 20:18
399 查看
一、进程通信
(一)、Linux进程间通信有以下几个版本:1、UNIX进程间通信
2、基于system进程间通信
3、基于POSIX进程间通信
(二)、进程间通信方式
1、管道(pipe)与有名管道(FIFO)
2、信号(singal)
3、消息队列
4、共享内存
5、信号量
6、套接字(sockfd)
(三)、管道
特点:
1、单向,先进先出,尾部写,头部读
2、读完变删除
3、当管道数据已满或管道内无数据时,进程会阻塞
无名管道:父子进程之间的通信
有名管道:任意两个进程之间的通信
4、无名管道创建方式:
int pipe(int fields[2]);
此函数创建两个文件描述符:fields[0]、fields[1],第一个文件以只读方式打开,为读取端,将fields[0]的文件读入管道。第二个文件以只写方式打开,将管道内的文件写入fields[1];
注意点:
应该在fork之前先创建管道。如图释:
例子:
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int pipe_fd[2];
if(pipe(pipe_fd)<0)
{
printf("pipe create error\n");
return -1;
}
else
printf("pipe create success\n");
close(pipe_fd[0]);
close(pipe_fd[1]);
}如果是父进程给子进程发消息:
父进程:
先close(fd[0]);把读关掉,先往里写
子进程:
先close(fd[1]);
5、有名管道创建方式
int mkfifo(const char * pathname,mode_t mode);
pathname:FIFO文件路径 mode:该文件的权限
(四)、共享内存(最快的方式)
头文件:#include <sys/shm.h>
创建共享内存两步骤:
1、创建共享内存:shmget 开辟内存
int shmget(key_t key,int size,int shmflg);
key:两个键值:0/IPC_PRIVATE
如果成功,返回共享内存标识符,如果失败,返回-1
2、映射共享内存:shmat 程序共享虚拟地址
char shmat(int shmid,char *chmaddr,int flag);
shmid:内存标识符 flag:置0
一旦创建了一个FIFO,就可用open打开它,一般的文件访问函数(close、read、write等)都可用于FIFO
(五)、消息队列
头文件:#include <sys/msg.h>
可传送有格式的字节流
消息队列的创建
1、创建消息队列需要先申请键值
key_t ftok(char *pathname,char proj);
pathname:文件名 proj:随机取
成功返回键值
2、int msgget(int key_t,int msgflg);
key_t:键值 msgflag:IPC_CREATE
返回值:消息队列描述符
3、int msgsnd(int msqid,struct msgbuf *msgp,int msgsz,int msgflg);
msqid:消息队列描述符
msgp:
struct msgbuf
{
int type; //不可变
char buffer[1025]; //发的消息
};
msgsz:消息大小
msgflg:IPC_NOWAIT(不堵塞)
4、int msgrcv(int msqid,struct msgbuf *msggp,int msgsz,long msgty,int msgflg);
msqid:消息队列描述字
msgp:
struct msgbuf
{
int type; //不可变
char buffer[1025]; //发的消息
};
msgsz:消息大小
msgty:第几个结构体
msgflg:IPC_NOWAIT
二、信号
(一)、信号处理方式:
1、忽略(其中SIGKILL和SIGSTOP不可忽略)
2、执行用户希望的动作
3、执行系统的默认动作
(二)、kill和raise
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int signo)
int raise(int signo)
kill的pid参数有四种不同的情况:
1、pid>0
将信号发送给进程ID为pid的进程。
2、pid == 0
将信号发送给同组的进程。
3、pid < 0
将信号发送给其进程组ID等于pid绝对值的进程。
4、pid ==-1
将信号发送给所有进程。
(三)、alarm
#include <signal.h>
unsigned int alarm(unsigned int seconds)
参数为经过多少秒发出警告
(四)、singal
例子:不可强制退出
#include <stdio.h>
#include <signal.h>
void func(int signal)
{
if(signal == SIGINT)
{
printf("ctrl + c!\n");
}
}
int main()
{
signal(SIGINT,func);
while(1)
{
printf("hello wrold!\n");
pause();
}
}
三、多线程编程
(一)、多线程特点
1、共享数据段,线程之间彼此切换所需的时间短,通信方式简单,使CPU系统更加有效,改善程序结构
(二)、线程的进程的区别
(三)、相关API:
头文件:#include <pthread.h>
1、创建线程
pthread_t id;
pthread_create(&id,NULL,print_msg,NULL);
可以重复创建,重复调用,谁先创建谁先执行,创建线程的程序一结束,所有子线程结束
2、线程等待函数
作用:主线程等待子线程结束了主线程才可结束
pthread_join(id,NULL);
3、pthread_exit(NULL)
在子线程中将该线程结束
4、第四个参数的使用
(四)、线程同步
保证线程同步的三种方法
1、互斥量(互斥锁) 2、信号灯 3、多量变量
过程:
全局变量中,先定义一把锁:pthread_mutex_t mutex;
主线程中初始化互斥锁:pthread_mutex_init(&mutex,NULL);
上锁:int pthread_mutex_lock(&mutex);
解锁:int pthread_mutex_unlock(&mutex);
例子:
#include <stdio.h>
#include <pthread.h>
int ticket = 10;
pthread_mutex_t mutex;
void sell_ticket(void * arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
if(ticket > 0)
{
sleep(1);
}
else
{
pthread_mutex_unlock(&mutex);
break;
}
printf("Left tickets:%d\n",--ticket);
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t id1;
pthread_t id2;
pthread_t id3;
pthread_mutex_init(&mutex,NULL);
pthread_create(&id1,NULL,(void *)sell_ticket,NULL);
pthread_create(&id2,NULL,(void *)sell_ticket,NULL);
pthread_create(&id3,NULL,(void *)sell_ticket,NULL);
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_join(id3,NULL);
return 0;
}
相关文章推荐
- Linux进程通信(2):信号(下)
- Linux进程通信(2):信号(上)
- Linux进程通信(3):信号量
- 有名管道和无名管道
- 进程间通信共享内存
- shmdt与shmctl的区别
- 进程间通信————管道
- 进程间通信-Windows
- CentOS6.5 安装CPAN,从而安装perl的各种模块
- linux ls和 ll 命令
- Linux的多任务多进程
- 转:使用rsync在linux(服务端)与windows(客户端)之间同步
- 每天一个Linux命令(1):ls命令
- 每天一个Linux命令(1):ls命令
- 每天一个Linux命令(1):ls命令
- 每天一个Linux命令(1):ls命令
- 每天一个Linux命令(1):ls命令
- 每天一个Linux命令(1):ls命令
- 每天一个Linux命令(1):ls命令
- 每天一个Linux命令(1):ls命令