一 无名信号量用于有血缘关系的进程间的互斥
void my_printf(void *arg)
{
char *str = (char *)arg;
while(1)
{
int n = 0;
while(*(str+n) != '\0')
{
printf("%c", *(str+n));
fflush(stdout);
n++;
sleep(1);
}
}
return ;
}
int main(void)
{
//定义一个无名信号量
//MAP_ANONYMOUS是匿名映射;-1是不需要文件描述符
sem_t * sem = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
//初始化无名信号量sem。第一个1表示进程间的,第二个1表示初始化为1
sem_init(sem, 1,1);
//创建子进程
pid_t pid;
pid = fork();
if(pid == 0) //子进程
{
sem_wait(sem);
my_printf("123456");
sem_post(sem);
return 0;
}
//主进程
sem_wait(sem);
my_printf("abcdef");
sem_post(sem);
//销毁信号量
sem_destroy(sem);
return 0;
}
二 无名信号量用于有血缘关系的进程间的同步
void my_printf(void *arg)
{
char *str = (char *)arg;
int n = 0;
while(*(str+n) != '\0')
{
printf("%c", *(str+n));
fflush(stdout);
n++;
sleep(1);
}
return ;
}
int main(void)
{
//定义两个无名信号量
//MAP_ANONYMOUS是匿名映射;-1是不需要文件描述符
sem_t * sem1 = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
sem_t * sem2 = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
//初始化无名信号量sem。第一个1表示进程间的,第二个1表示初始化为1
sem_init(sem1, 1,1);
sem_init(sem2, 1,0);
//创建子进程
pid_t pid;
pid = fork();
if(pid == 0) //子进程
{
sem_wait(sem1);
my_printf("123456");
sem_post(sem2);
return 0;
}
//主进程
sem_wait(sem2);
my_printf("abcdef");
sem_post(sem1);
//销毁信号量
sem_destroy(sem1);
sem_destroy(sem2);
return 0;
}
三 有名信号量用于无血缘关系的进程间的互斥
3.1 创建有名信号量函数sem_open
1. 需要的头文件和函数原型:
//信号量存在
sem_t * sem_open(const char *name, int oflag);
//信号量不存在
sem_t * sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
2. 功能:
创建一个信号量
3. 参数:
name:信号量的名字
oflag:sem_open函数的权限标志
mode:文件权限(可读,可写,可执行0777)的设置
value:信号量的初始值
4. 返回值:
成功:信号量的地址
失败:SEM_FAILED
3.2 信号量的关闭函数sem_close
int sem_close(sem_t *sem);
功能:关闭信号量
参数:信号量的地址
返回值:成功0;失败-1
3.3 信号量文件的删除函数sem_unlink
int sem_unlink(const char *name);
功能:删除信号量文件
参数:信号量的文件名
返回值:成功0;失败-1
3.4 代码实现
void my_printf(void *arg)
{
char *str = (char *)arg;
int n = 0;
while(*(str+n) != '\0')
{
printf("%c", *(str+n));
fflush(stdout);
n++;
sleep(1);
}
return ;
}
int main(void)
{
//创建一个有名信号量sem_open, 最后一个参数是初始值
sem_t * sem = sem_open("sem", O_RDWR|O_CREAT, 0666, 1);
//P 操作
sem_wait(sem);
//执行任务
my_printf("123456\n");
//V 操作
sem_post(sem);
//关闭信号量
sem_close(sem);
//销毁信号量
sem_destroy(sem);
return 0;
}
四 有名信号量用于无血缘关系的进程间的同步
4.1 进程1的代码
void my_printf(void *arg)
{
char *str = (char *)arg;
int n = 0;
while(*(str+n) != '\0')
{
printf("%c", *(str+n));
fflush(stdout);
n++;
sleep(1);
}
return ;
}
int main(void)
{
//创建两个有名信号量sem_open, 最后一个参数是初始值
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 操作
sem_wait(sem1);
//执行任务
my_printf("123456\n");
//V 操作
sem_post(sem2);
//关闭信号量
sem_close(sem1);
sem_close(sem2);
//销毁信号量
sem_destroy(sem1);
sem_destroy(sem2);
return 0;
}
4.2 进程2的代码
void my_printf(void *arg)
{
char *str = (char *)arg;
int n = 0;
while(*(str+n) != '\0')
{
printf("%c", *(str+n));
fflush(stdout);
n++;
sleep(1);
}
return ;
}
int main(void)
{
//创建两个有名信号量sem_open, 最后一个参数是初始值
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 操作
sem_wait(sem2);
//执行任务
my_printf("abcdef\n");
//V 操作
sem_post(sem1);
//关闭信号量
sem_close(sem1);
sem_close(sem2);
//销毁信号量
sem_destroy(sem1);
sem_destroy(sem2);
return 0;
}
|