一 无名信号量用于有血缘关系的进程间的互斥
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
二 无名信号量用于有血缘关系的进程间的同步
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
三 有名信号量用于无血缘关系的进程间的互斥
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
四 有名信号量用于无血缘关系的进程间的同步
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
