Linux编程题:信号量同步三进程依次打印若干次ABC

Linux编程题:信号量同步三进程依次打印若干次ABC,第1张

Linux编程题:信号量同步三进程依次打印若干次ABC

三个进程依次打印ABC.....

思路及大致流程如下:

 思路取自这位大哥:

Linux编程题:创建3个线程分别打印abc,用信号量进行同步_cleverlemon的博客-CSDN博客

这位大哥写的是线程,不需要自己封装sem那些初始化函数,pv *** 作函数以及销毁函数,这篇写的是多进程,麻烦一些,大致思路一毛一样

来看代码实现:

先来对sem所需的初始化函数,pv *** 作函数,销毁函数进行封装:

sem.h

#include 
#include 
#include 
#include 
#include 

#define SEM_NUM 3
#define SEM1 0
#define SEM2 1
#define SEM3 2
union semun
{
    int val;
};
int sem_init( );
void sem_p( int index); //0,1,2因为有三个信号量  得对具体信号量进行 *** 作
void sem_v(int index );
void sem destroy();

sem.c

#include "sem.h"

static int semid = - 1;
int sem_init()
{
    semid = semget ( (key t)1234,SEM_NUM, IPC_CREAT|IPC_EXCL|0600);
    if ( semid == -1 )
    {
        semid = semget((key_t)1234,SEM_NUM,0600);
        if(semid == -1)
        {    
            printf("semget errn");
            return -1;
        }
    }
    else
    {
        int arr[SEM_NUM] = {1,0,0};
        for (int i = 0; i < SEM_NUM; i++)
	    {
		    union semnu a;//给联合体起别名a
		    a.val = arr[i];
		    if (semctl(semid, i, SETVAL, a) == -1)  //semid是信号量集标识符  i是信号量集数组上的下标,表示某一个信号量  a是联合体的别名   SETVAL是命令对信号量赋值
		    { 
			    printf("semctl errn");
			    return -1;
		    }
	    }
    }
}
void sem_p( int index)
{
    if ( index < 0 || index >= SEM_NUM ) //下标越界直接终止程序
    {
        return;
    }
    struct sembuf buf;
    buf. sem_num = index;
    buf.sem_op = -1;// p *** 作
    buf.sem_flg = SEM_UNDO;  //防止获得信号量之后程序异常结束  SEM_UNDO的作用就是帮你把信号量释放
    if ( semop ( semid , &buf ,1)== -1 )
    {
        return :
    }

}
void sem_v(int index)
{
    if ( index < 0 || index >= SEM_NUM ) //下标越界直接终止程序
    {
        return;
    }
    struct sembuf buf ;buf. sem_num = index;buf.sem_op = 1;// v *** 作
    buf.sem_flg = SEM_UNDO;
    if ( semop ( semid , &buf ,1)== -1 ) //这块semop(semid,&buf,1)中的1就是只定义了1个信号量buf,如果后面是3的话  前面那块就得写buf[3]
    {
        return :
    }
}
void sem_destroy()
{
    if(semctl(semid,0,IPC_RMID) == -1) //这块semctl(semid , 0 ,IPC_RMID)里面的参数,那个0激素个占位的作用  没什么实质性的作用  销毁的话 只需要semid和命令IPC_RMID就行了
    {
        return ;
    }
}

a.c的实现:

#include "sem. h"
int main()
{
	int res = sem_init();
	if (res == -1)
	{
		return;
	}
	for (int i = 0; i < 5; i++) 
	{
		sem_p(SEM1);
        printf("A"); //然后将该程序赋值三份  改一下pv操作中的参数  再给打印的A换成B/C 
        fflush(stdout); 
        sem_v(SEM2);
	}
	sem_destroy() :
    return 0;
}

b.c的实现:

#include "sem. h"
int main()
{
	int res = sem_init();
	if (res == -1)
	{
		return;
	}
	for (int i = 0; i < 5; i++) 
	{
		sem_p(SEM2);
        printf("B"); //然后将该程序赋值三份  改一下pv操作中的参数  再给打印的A换成B/C 
        fflush(stdout); 
        sem_v(SEM3);
	}
	sem_destroy():
    return 0;
}

c.c的实现:

#include "sem. h"
int main()
{
	int res = sem_init();
	if (res == -1)
	{
		return;
	}
	for (int i = 0; i < 5; i++) 
	{
		sem_p(SEM3);
        printf("C"); //然后将该程序赋值三份  改一下pv操作中的参数  再给打印的A换成B/C 
        fflush(stdout); 
        sem_v(SEM1);
	}
	sem_destroy():
    return 0;
}
所有代码搞定  来看执行

对所有程序进行编译链接:

 运行结果:

 我编译链接的时候semid给错了  所以打印出来就变成了CBA  其实思想一样的,依次打印就好了  我就懒得改了!

“只有学习才可以让生活变得充实起来!”

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5433852.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存