linux进程间通信问题 我想用共享内存的方式实现信号量控制一个不许并行的的函数 请问下面我的代码合理吗
初始化共享内存:intshmid;int*shmaddr;if((shmid=shmget(MY_KEY,SIZE,IPC_CREAT))==-1){printf("sh...
初始化共享内存:
int shmid;
int *shmaddr;
if((shmid = shmget(MY_KEY,SIZE,IPC_CREAT)) ==-1)
{
printf("shmget error!\n");
exit(1);
}
if((shmaddr = shmat(shmid,0,0)) == (void *)-1)
{
printf("shmat error!\n");
exit(1);
}
在进程操作中用信号量控制一个不能并行的函数:
while( *shmaddr );
*shmaddr = 1;
/*..........只能单独进行的函数.........*/
*shmaddr = 0;
望大家踊跃赐教~ 展开
int shmid;
int *shmaddr;
if((shmid = shmget(MY_KEY,SIZE,IPC_CREAT)) ==-1)
{
printf("shmget error!\n");
exit(1);
}
if((shmaddr = shmat(shmid,0,0)) == (void *)-1)
{
printf("shmat error!\n");
exit(1);
}
在进程操作中用信号量控制一个不能并行的函数:
while( *shmaddr );
*shmaddr = 1;
/*..........只能单独进行的函数.........*/
*shmaddr = 0;
望大家踊跃赐教~ 展开
2个回答
展开全部
看你好像完全搞混了。。。什么叫用共享内存的方式实现信号量控制不能并行的代码?
首先共享内存和信号量都可以实现进程间通信,但是他们的作用或者说使用的方向是有明显的区别的:
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。
首先共享内存和信号量都可以实现进程间通信,但是他们的作用或者说使用的方向是有明显的区别的:
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。
追问
也同样感谢您的回答 无奈只能取一个答案
展开全部
我想你的目的是有一段代码 (即你标的 /*..........只能单独进行的函数.........*/)
在任意时刻最多只能有最多一个进程执行,是吧。
首先,你的做法是错的…… 简单的说,原因是由于
while( *shmaddr );
*shmaddr = 1;
这两行代码不是一个原子操作,从while判断出 *shmaddr等于0 到 *shmaddr=1 之间,另外一个或多个进程可能也会得到 *shmaddr==0 的判断,从而导致多个进程同时进入 /*..........只能单独进行的函数.........*/
具体关于互斥的基本原理,以及你为什么错,可以找一本讲操作系统原理 (关于进程同步的内容)去看。
所以,用 shared memory 来实现进程同步肯定是不行的,正确的做法是使用 semaphore, 具体可以参考 《unix 环境高级编程》中关于 semaphore (信号量)使用的章节。
在任意时刻最多只能有最多一个进程执行,是吧。
首先,你的做法是错的…… 简单的说,原因是由于
while( *shmaddr );
*shmaddr = 1;
这两行代码不是一个原子操作,从while判断出 *shmaddr等于0 到 *shmaddr=1 之间,另外一个或多个进程可能也会得到 *shmaddr==0 的判断,从而导致多个进程同时进入 /*..........只能单独进行的函数.........*/
具体关于互斥的基本原理,以及你为什么错,可以找一本讲操作系统原理 (关于进程同步的内容)去看。
所以,用 shared memory 来实现进程同步肯定是不行的,正确的做法是使用 semaphore, 具体可以参考 《unix 环境高级编程》中关于 semaphore (信号量)使用的章节。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询