linux进程间通信问题 我想用共享内存的方式实现信号量控制一个不许并行的的函数 请问下面我的代码合理吗

linux进程间通信问题 我想用共享内存的方式实现信号量控制一个不许并行的的函数 请问下面我的代码合理吗,第1张

看你好像完全搞混了。。。什么叫用共享内存的方式实现信号量控制不能并行的代码?

首先共享内存和信号量都可以实现进程间通信,但是他们的作用或者说使用的方向是有明显的区别的:

1:共享内存是创建一块内存区域,多个进程可以同时访问该区域,一般用于进程间数据传输,效率比较明显。

2:信号量则完全不同,信号量主要是用来控制临界资源的访问,也就是你说的不能并行的函数/代码。

3:说一下实现,共享内存直接用API就可以了,信号量一般会进行封装,类似于对链表的操作进行一些简单的函数封装一样,下面给出信号量的使用实例代码,可以参考:

sem_ctl.c文件内容:

int init_sem(int sem_id,int init_value)

{

union semun sem_union

sem_union.val = init_value

if(semctl(sem_id,0,SETVAL,sem_union) == -1)

{

perror("semctl")

return -1

}

return 0

}

int del_sem(int sem_id)

{

union semun sem_union

if(semctl(sem_id,0,IPC_RMID,sem_union) == -1)

{

perror("delete semaphore")

return -1

}

return 0

}

int sem_p(int sem_id)

{

struct sembuf sem_b

sem_b.sem_num = 0

sem_b.sem_op = -1

sem_b.sem_flg = SEM_UNDO

if(semop(sem_id,&sem_b,1) ==-1)

{

perror("P operation")

return -1

}

return 0

}

int sem_v(int sem_id)

{

struct sembuf sem_b

sem_b.sem_num = 0

sem_b.sem_op = 1

sem_b.sem_flg = SEM_UNDO

if(semop(sem_id,&sem_b,1) == -1)

{

perror("V opration")

return -1

}

return 0

}

sem_ctl.h文件内容:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#define MAX 128

int count //全局变量,即临界资源

union semun{

int val

struct semid_ds *buf

unsigned short *array

struct seminfo *__buf

}

int init_sem(int sem_id,int init_value)

int del_sem(int sem_id)

int sem_p(int sem_id)

int sem_v(int sem_id)

在应用程序中只要包含sem_ctl.h就可以使用信号量的p、v操作了,下面给出2个c程序同时操作该信号量的情况,类似于:

server.c文件内容如下:

#include "util.h"

#include <signal.h>

int semid

void sighandler(int signo)

{

del_sem(semid)

exit(0)

}

void server()

{

key_t key

initcount()

if((key = ftok(".",'e')) == -1)

{

perror("ftok")

exit(1)

}

if((semid = semget(key,1,0666|IPC_CREAT|IPC_EXCL)) == -1)

{

perror("semget")

exit(1)

}

printf("the semid is :%d\n",semid)

init_sem(semid, 0)

signal(SIGINT,sighandler)

signal(SIGUSR1,sighandler)

signal(SIGALRM,sighandler)

while(1)

{

sem_p(semid)

/* do something */

printf("count =%d\n",count++)

sem_v(semid)

sleep(2)

}

}

int main(void)

{

server()

}

client.c文件内容如下:

#include "sem_ctl.h"

void custom()

{

int semid

key_t key

if((key = ftok(".",'e')) == -1)

{

perror("ftok")

exit(1)

}

if((semid = semget(key,0,0)) == -1)

{

perror("semget")

exit(1)

}

printf("the semid is :%d\n",semid)

while(1)

{

sem_p(semid) //获得信号量,同一时间只有一个进程能获得该信号量

/* do something */

printf("count =%d\n",count++)

sem_v(semid)//释放信号量

sleep(2)

}

}

int main(void)

{

custom()

}

编译好,运行的时候先运行server再运行client。

分配与初始化信号量是两个相互独立的操作。以 0 为第二参数,以 SETALL 为第三个参数调用 semctl 可以对一个信号量组进行初始化。第四个参数是一个 semun 对象,且它的 array 字段指向一个 unsigned short数组。数组中的每个值均用于初始化该组中的一个信号量。

代码 5.3 展示了初始化一个二元信号量的函数。

代码 5.3 (sem_init.c) 初始化一个二元信号量

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

/* 我们必须自己定义 union semun。*/

union semun

{

int val

struct semid_ds *buf

unsigned short int *array

struct seminfo *__buf

}

/* 将一个二元信号量初始化为 1。*/

int binary_semaphore_initialize (int semid)

{

union semun argument

unsigned short values[1]

values[0] = 1

argument.array = values

return semctl (semid, 0, SETALL, argument)

}


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/380295.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-15
下一篇2023-05-15

发表评论

登录后才能评论

评论列表(0条)

    保存