目录
知识点1【无名信号量完成 有血缘关系的进程间 互斥】
总结:
知识点2【有名信号量 没有血缘进程互斥】
1、创建一个有名信号量
2、信号量的关闭:
3、信号量文件的删除
4、P操作 sem_wait V操作sem_post 销毁信号量sem_destroy
知识点3【有名信号量 没有血缘进程同步】
知识点1【无名信号量完成 有血缘关系的进程间 互斥】
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/mman.h>void myPrintf(char *str){while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}int main(int argc, char const *argv[])
{//互斥 只需要 定义一个信号量sem_t *sem;//匿名映射mmap MAP_ANONYMOUS -1不用打开文件sem = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);//信号量 sem 初始化 第一个1表示进程间同步互斥 第二个1信号量的初始值1sem_init(sem, 1, 1);pid_t pid = fork();if(pid == 0){//子进程//p 操作-1sem_wait(sem);myPrintf("hello");//v 操作+1sem_post(sem);}else if(pid > 0){//父进程sem_wait(sem);myPrintf("world");sem_post(sem);}getchar();//销毁信号量sem_destroy(sem);//销毁mmapmunmap(sem, sizeof(sem_t));return 0;
}brightsky@Bright-SKY:~/codes/blog$ ./a.out
worldhello
总结:
无名信号量 (sem_t sem) 线程同步互斥。
无名信号量(mmap 匿名映射) 有血缘关系的进程同步互斥
有名信号量 无血缘关系的进程同步互斥
知识点2【有名信号量 没有血缘进程互斥】
1、创建一个有名信号量
#include <fcntl.h> /* For O_* constants */#include <sys/stat.h> /* For mode constants */#include <semaphore.h>//信号量存在
sem_t *sem_open(const char *name, int oflag);
//信号量不存在
sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);
功能:
创建一个信号量
参数:
name:信号量的名字
oflag:sem_open函数的权限标志
mode:文件权限(可读、可写、可执行 0777)的设置
value:信号量的初始值
返回值:
信号量的地址,失败:SEM_FAILED
2、信号量的关闭:
int sem_close(sem_t *sem);
功能:关闭信号量
参数:信号量的的地址
返回值:成功0 失败-1
3、信号量文件的删除
#include <semaphore.h>
int sem_unlink(const char *name);
功能:删除信号量的文件
参数:信号量的文件名
返回值:成功0 失败-1
4、P操作 sem_wait V操作sem_post 销毁信号量sem_destroy
04_fork01.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<fcntl.h>void myPrintf(char *str)
{while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}
int main()
{//互斥需要一个信号量sem_t *sem = sem_open("sem", O_RDWR|O_CREAT,0666,1);//p操作-1sem_wait(sem);myPrintf("hello hehe haha");//v操作+1sem_post(sem);//关闭信号量sem_close(sem);return 0;
}
04_fork02.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<fcntl.h>void myPrintf(char *str)
{while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}
int main()
{//互斥需要一个信号量sem_t *sem = sem_open("sem", O_RDWR|O_CREAT,0666,1);//p操作-1sem_wait(sem);myPrintf("world xixi lala");//v操作+1sem_post(sem);//关闭信号量sem_close(sem);return 0;
}
运行结果:编译的时候记得加-lpthread
知识点3【有名信号量 没有血缘进程同步】
04_fork01.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<fcntl.h>void myPrintf(char *str)
{while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}
int main()
{//同步需要2个信号量sem_t *sem1 = sem_open("sem1", O_RDWR|O_CREAT,0666,1);sem_t *sem2 = sem_open("sem2", O_RDWR|O_CREAT,0666,0);//p操作-1sem_wait(sem1);myPrintf("hello hehe haha");//v操作+1sem_post(sem2);//关闭信号量sem_close(sem1);sem_close(sem2);return 0;
}
04_fork02.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<fcntl.h>void myPrintf(char *str)
{while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}
int main()
{//同步需要2个信号量sem_t *sem1 = sem_open("sem1", O_RDWR|O_CREAT,0666,1);sem_t *sem2 = sem_open("sem2", O_RDWR|O_CREAT,0666,0);//p操作-1sem_wait(sem2);myPrintf("world xixi lala");//v操作+1sem_post(sem1);//关闭信号量sem_close(sem1);sem_close(sem2);return 0;
}