`
haoningabc
  • 浏览: 1483114 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

进程间通信的例子-信号量

阅读更多
消息队列,信号量,共享内存
vim-------------------
im中翻页的命令

    整页翻页 ctrl-f ctrl-b
    f就是forword b就是backward

    翻半页
    ctrl-d ctlr-u
    d=down u=up

    滚一行
    ctrl-e ctrl-y

    zz 让光标所杂的行居屏幕中央
    zt 让光标所杂的行居屏幕最上一行 t=top
    zb 让光标所杂的行居屏幕最下一行 b=bottom
-------------------------------
/* After the #includes, the function prototypes and the global variable, we come to the
 main function. There the semaphore is created with a call to semget, which returns the
 semaphore ID. If the program is the first to be called (i.e. it's called with a parameter
 and argc > 1), a call is made to set_semvalue to initialize the semaphore and op_char is
 set to X. */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <sys/sem.h>

#include "semun.h"

static int set_semvalue(void);  //给信号赋值,设置属性等
static void del_semvalue(void);
static int semaphore_p(void);
static int semaphore_v(void);

static int sem_id;


int main(int argc, char *argv[])
{
    int i;
    int pause_time;
    char op_char = 'O';

    srand((unsigned int)getpid());
    
    sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);  //初始化信号量(相当于open)

    if (argc > 1)    //是起始程序
     {
        if (!set_semvalue()) {
            fprintf(stderr, "Failed to initialize semaphore\n");
            exit(EXIT_FAILURE);
        }
        op_char = 'X';
        sleep(2);
    }

/* Then we have a loop which enters and leaves the critical section ten times.
 There, we first make a call to semaphore_p which sets the semaphore to wait, as
 this program is about to enter the critical section. */

    for(i = 0; i < 10; i++) {        

        if (!semaphore_p())
        	 exit(EXIT_FAILURE);
        printf("%c", op_char);fflush(stdout);
        pause_time = rand() % 3;
        sleep(pause_time);
        printf("%c", op_char);fflush(stdout);

/* After the critical section, we call semaphore_v, setting the semaphore available,
 before going through the for loop again after a random wait. After the loop, the call
 to del_semvalue is made to clean up the code. */

        if (!semaphore_v()) 
        	exit(EXIT_FAILURE);
        
        pause_time = rand() % 2;
        sleep(pause_time);
    }    

    printf("\n%d - finished\n", getpid());

    if (argc > 1) {    
        sleep(10);
        del_semvalue();
    }
        
    exit(EXIT_SUCCESS);
}

/* The function set_semvalue initializes the semaphore using the SETVAL command in a
 semctl call. We need to do this before we can use the semaphore. */

//给信号量赋初值
static int set_semvalue(void)
{
    union semun sem_union;

    sem_union.val = 1;
    if (semctl(sem_id, 0, SETVAL, sem_union) == -1) //semctl()的二参是下标
    	return(0);
    return(1);
}

/* The del_semvalue function has almost the same form, except the call to semctl uses
 the command IPC_RMID to remove the semaphore's ID. */

//销毁信号量
static void del_semvalue(void)
{
    union semun sem_union;
    
    if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
        fprintf(stderr, "Failed to delete semaphore\n");
}

/* semaphore_p changes the semaphore by -1 (waiting). */

static int semaphore_p(void)
{
    struct sembuf sem_b;
    
    sem_b.sem_num = 0;
    sem_b.sem_op = -1; /* P() */
    sem_b.sem_flg = SEM_UNDO;
    if (semop(sem_id, &sem_b, 1) == -1) {
        fprintf(stderr, "semaphore_p failed\n");
        return(0);
    }
    return(1);
}

/* semaphore_v is similar except for setting the sem_op part of the sembuf structure to 1,
 so that the semaphore becomes available. */

static int semaphore_v(void)
{
    struct sembuf sem_b;
    
    sem_b.sem_num = 0;
    sem_b.sem_op = 1; /* V() */
    sem_b.sem_flg = SEM_UNDO;
    if (semop(sem_id, &sem_b, 1) == -1) {
        fprintf(stderr, "semaphore_v failed\n");
        return(0);
    }
    return(1);
}

root@ubuntu:~/test/SourceCode/ch14# cat semun.h 
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
    /* union semun is defined by including <sys/sem.h> */
#else
    /* according to X/OPEN we have to define it ourselves */
    union semun {
        int val;                    /* value for SETVAL */
        struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
        unsigned short int *array;  /* array for GETALL, SETALL */
        struct seminfo *__buf;      /* buffer for IPC_INFO */
    };
#endif

先执行
stty -tostop
这个是确保产生的tty的输出的后台程序不会引发系统生成的一个信号

./sem1 1 &
./sem1


打印结果就是
root@ubuntu:~/test/SourceCode/ch14# ./sem1 1&  
[1] 14437
root@ubuntu:~/test/SourceCode/ch14# ./sem1
OOXXOOXXOOXXOOXXOOXXXXOOXXOOXXOOXXOOXX
14437 - finished
OO
14438 - finished
root@ubuntu:~/test/SourceCode/ch14# 


发现了没?XX和OO都是成对出现的

信号量就是一个全局的锁,在多进程并行的时候,保持数据一致性的一个东西哦
分享到:
评论

相关推荐

    Linux进程间通信-信号量通信进程互斥实例.pdf

    【Linux进程间通信】在操作系统中,进程间通信(Inter-Process Communication, IPC)是不同进程之间交换数据的重要机制。Linux提供了多种IPC方式,包括管道、消息队列、共享内存、信号量等。本实例主要关注的是...

    进程间通信例子

    这个“进程间通信例子”可能是针对Windows Forms(WinForm)应用程序提供的一种实践示例,展示了如何在不同的进程中发送和接收信息。 1. **管道**:管道是一种半双工的通信方式,允许数据在两个进程间单向流动。...

    使用共享内存及信号量实现进程间通信例子

    在计算机系统中,进程间通信(IPC,Inter-Process Communication)是多个进程协同工作时必不可少的一部分。本示例代码着重于使用共享内存和信号量来解决进程间的通信和同步问题,这是一种高效且灵活的方法,特别是在...

    UNIX网络编程卷2进程间通信--部分源代码

    进程间通信是操作系统中多进程协作的基础,它包括了管道、信号量、共享内存、消息队列、套接字等多种机制。这些机制允许不同进程之间交换数据,实现同步和协调。在这些源代码中,我们可以看到这些通信方式的实际...

    Linux进程间通信-信号通信信号发送实例.pdf

    总结来说,信号通信是Linux IPC的重要组成部分,它提供了简单而快速的进程间通信方式。通过`kill`、`raise`和`sigqueue`等函数,程序员可以灵活地控制和传递信息,实现进程间的交互。然而,由于信号携带信息有限,...

    Linux进程间通信-信号通信定时信号实例.pdf

    信号是Linux系统中进程间通信的一种轻量级方式,它能够用来中断进程的执行、改变进程状态或者通知进程发生了某些系统事件。在示例程序中,使用了`&lt;signal.h&gt;`头文件,这是处理信号的必备库。 定时信号通常与`alarm...

    操作系统实验-信号量机制实现进程同步

    在多道程序设计中,进程同步是操作系统中的一个重要概念,它涉及到多个并发进程间的协调和通信,确保它们能正确、有序地访问共享资源,避免数据竞争和死锁等问题的发生。 信号量机制是实现进程同步的一种有效工具,...

    linux进程间通信——信号机制

    总结来说,Linux的信号机制是进程间通信的重要组成部分,它提供了简单但灵活的方式来处理系统事件和进程间的交互。`signal`和`sigaction`函数为程序员提供了处理信号的工具,使得我们可以根据需求定制信号的响应行为...

    全面深入的学习进程间通信机制之一:信号量

    ### 全面深入的学习进程间通信机制之一:信号量 #### 一、信号量概述 **信号量**是一种用于管理进程间对共享资源访问的重要机制,尤其在操作系统中扮演着核心角色。它能够确保资源的一致性和完整性,避免了并发...

    Linux进程间通信课件代码.rar

    2. 7-5.c、7-10.c 和 7-7.c 同样可能代表不同章节或话题下的代码示例,这些例子可能逐步引导学习者了解进程间通信的不同层面,如信号量、管道、消息队列等。 3. 7-12write.c 和 7-12read.c 可能涉及到特定的进程间...

    delphi进程间通讯例子

    总的来说,这个Delphi例子旨在演示如何使用自定义消息和共享内存进行进程间通信,开发者可以从源代码中学习如何创建和管理这些通信机制,理解Delphi中IPC的实现细节。这不仅有助于深入理解Delphi编程,还能为解决多...

    linux系统进程间通信——共享内存(System V版本)

    之前用过Prosix版本的共享内存和信号量,一直没有实践System V版本的,主要是因为其信号量集的概念操作有些复杂,今天试着写一个SV版本的共享内存进程间通信,使用信号量同步。程序提供了几个简单的用于操作SV版本...

    Linux进程间通信的例子

    资源中包含了Linux进程间通信的例子,同时有源文件和可执行文件。 源码主要包含了Linux下IPC机制的本地进程通信方式,包含了IPC共享内存,IPC信号量,IPC消息队列的实现,以及Linux下判断进程退出原因的示例程序。

    VS2008代码式例:进程间通信,本人亲测OK

    在编程领域,进程间通信(IPC,Inter-Process Communication)是一项关键的技术,它允许不同的进程之间交换数据和信号,以实现协同工作。本示例基于Visual Studio 2008(VS2008),提供了关于如何进行进程间通信的...

    UNIX网络编程 卷2:进程间通信

     10.12 进程间共享信号量 205  10.13 信号量限制 206  10.14 使用FIFO实现信号量 206  10.15 使用内存映射I/O实现信号量 210  10.16 使用System V信号量实现Posix信号量 218  10.17 小结 224  习题 225  第...

    进程间通信,进程间通信

    通过学习和实践这个例子,你可以深入理解命名管道的工作原理,掌握在Windows环境下如何使用命名管道进行进程间通信。此外,还可以进一步研究其他的IPC机制,如信号量、共享内存、套接字等,以增强自己在多进程编程...

    uCOS-Ⅱ 信号量.zip

    在uCOS-II中,信号量(Semaphore)是用于进程间通信和同步的重要机制,它允许任务之间共享资源或者进行复杂同步。在本资料包"uCOS-Ⅱ 信号量.zip"中,很可能是包含了关于如何在uCOS-II系统中使用信号量的教程或源...

    进程通信ec模块+源码+例程

    - 管道(Pipe):单向数据流,适合简单父子进程间通信。 - 有名管道(Named Pipe):也叫FIFO,允许不相关的进程间通信。 - 套接字(Socket):支持网络上的进程间通信,双向通信。 - 共享内存:进程可以直接...

    进程间通讯---共享内存的使用方法

    共享内存是一种高效的进程间通信(IPC,Inter-Process Communication)方式,它允许不同的进程直接读写同一块内存区域,无需通过任何中介。这种方式避免了数据复制,因此在速度上具有显著优势。本教程将深入探讨如何...

    在SELinux中保护进程间通信

    本文通过一个具体的例子来展示如何利用SELinux策略和传统的Linux IPC机制来实现安全的进程间通信。假设我们有两个进程A和B,它们需要通过消息队列进行通信。为了确保安全性,我们可以采取以下步骤: 1. **定义安全...

Global site tag (gtag.js) - Google Analytics