信号量(semaphore)是操作系统用来解决并发中的互斥和同步问题的一种方法。
信号量 (个数) --- 反映的是资源的数量
信号量的分类:信号无名量 ==》线程间通信
有名信号量 ==》进程间通信
sem_t sem
sem_t:信号量的类型,sem:信号量的变量
例如: sem_t sem_w;,sem_t sem_r;
sem_t sem_1;
sem_t sem_2;
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:将已经定义好的信号量赋值。
参数:sem 要初始化的信号量,pshared = 0 ;表示线程间使用信号量,!=0 ;表示进程间使用信号量,value 信号量的初始值,一般无名信号量都是二值信号量(0 1) ,0 表示红灯,进程暂停阻塞,1 表示绿灯,进程可以通过执行
返回值:成功 0,失败 -1;
sem_init(&sem_1,0,1);
sem_init(&sem_2,0,0);
sem_wait()/ sem_post()
P ===》申请资源===》申请一个二值信号量int sem_wait(sem_t *sem);
功能:判断当前sem信号量是否有资源可用。如果sem有资源(==1),则申请该资源,程序继续运行如果sem没有资源(==0),则线程阻塞等待,一旦有资源则自动申请资源并继续运行程序。
注意:sem 申请资源后会自动执行 sem = sem - 1;
参数:sem 要判断的信号量资源
返回值:成功 0 ,失败 -1
V ===》释放资源===》释放一个二值信号量,nt sem_post(sem_t *sem);
功能:函数可以将指定的sem信号量资源释放并默认执行,sem = sem+1; 线程在该函数上不会阻塞。
参数:sem 要释放资源的信号量
返回值:成功 0, 失败 -1;
void *doWin2(void *arg)
{
int i = 0;
while (1)
{
sem_wait(&sem_2);
if (ticket <= 0)
{
sem_post(&sem_1);
break;
}
ticket--; //1 => 0
printf("win2 sell ticket = %d\n",100-ticket); //100
sem_post(&sem_1);
}
pthread_exit(NULL);
}
int sem_destroy(sem_t *sem);
功能:使用完毕将指定的信号量销毁
参数:sem要销毁的信号量
返回值:成功 0,失败 -1;
sem_destroy(&sem_1);
sem_destroy(&sem_2);
进程创建好之后,父子进程的空间 相互独立 。
1、古老的通信方式
管道:无名管道 (1),有名管道 (2)
信号 (3)
2、IPC对象通信 system v BSD suse fedora kernel.org
消息队列 (4)
共享内存(*) //最高效 (5)
信号量集() //信号量 (6)
3、socket通信
网络通信 (7)
功能:创建一个管道
参数:pipefd //用来获取 管道的两端 ,读端pipefd[0] ,写端pipefd[1]
返回值:成功 0,失败 -1 && errno
#include
#include
#include
int main(int argc, const char *argv[])
{
int fd[2];
if (pipe(fd) < 0)
{
perror("pipe fail");
return -1;
}
char buf[] = "hello pipe\n";
write(fd[1],buf,strlen(buf));
char bufr[100] = {0};
read(fd[0],bufr,sizeof(bufr));
printf("bufr = %s\n",bufr);
return 0;
}
管道大小 65536字节 64k
管道操作特点 ,数据读走之后,认为就没了
1.读端存在,写管道
管道空:可以写数据
管道满:会造成-->写阻塞
2.读端不存在,写管道
系统会给进程发一个信号SIGPIPE(管道破裂)
3.写端存在,读管道
管道空,读不到数据,
这时会造成读操作阻塞
4.写端不存在,读管道
如果管道中有数据,则读取这些数据!
如果没有数据,读操作不阻塞,立即返回!