Chinaunix

标题: 两进程间通信问题 [打印本页]

作者: jqx55ah    时间: 2008-09-13 01:31
标题: 两进程间通信问题
下面的代码 是两个程序!一个输出,一个输入的!
无论先运行哪个 结果都是输出:“shmat error”!
是我的参数 设置错误吗?

#define BUF_SIZE 1024
#define MYKEY 24
int main()
{
int shmid;
char* shmptr;

if((shmid=shmget(MYKEY,BUF_SIZE,IPC_CREAT))==-1)
{
    printf("shmget error!\n");
    exit(1);
}

if((shmptr=shmat(shmid,0,0))==(void*)(-1))
{
    fprintf(stderr,"shmat eror!\n");
    exit(1);
}

while(1)
{
    printf("string:%s\n",shmptr);
    sleep(3000);
}
exit(0);
}
---------------------------------------------------------------------------
第二个进程!
#define BUF_SIZE 1024
#define MYKEY 24
int main()
{
    int shmid;
    char *shmptr;
   
    if((shmid=shmget(MYKEY,BUF_SIZE,IPC_CREAT))==-1)
    {
        printf("shmget error!\n");
        exit(1);
    }
   
    if((shmptr=shmat(shmid,0,0))==(void*)-1)
    {
        fprintf(stderr,"shmat error!\n");
        exit(1);
    }
   
    while(1)
    {
        scanf("input string:%s",shmptr);
    }
    exit(0);
}

[ 本帖最后由 jqx55ah 于 2008-9-13 01:56 编辑 ]
作者: timespace    时间: 2008-09-13 01:47
shmget(MYKEY,BUF_SIZE,IPC_CREAT) 连读写权限标志都没有?
作者: jqx55ah    时间: 2008-09-13 01:55
原帖由 timespace 于 2008-9-13 01:47 发表
shmget(MYKEY,BUF_SIZE,IPC_CREAT) 连读写权限标志都没有?

书上 是这样解释这个形式的:
当key不为IPC_PRIVATE,且flag设置为IPC_CREAT位,而没有设置IPC_EXCL位,则执行操作由key取值决定。
作者: timespace    时间: 2008-09-13 01:59
#define MYKEY 24
书上说可以这么用?
作者: jqx55ah    时间: 2008-09-13 02:01
原帖由 timespace 于 2008-9-13 01:59 发表
#define MYKEY 24
书上说可以这么用?

没有!但是书上的例题是这样的!
说实话,我不懂 这中形式的调用 是怎么由key的取值决定的

[ 本帖最后由 jqx55ah 于 2008-9-13 02:06 编辑 ]
作者: freezingdawn    时间: 2008-09-13 04:06

作者: waternie    时间: 2008-09-13 08:39
把errno打出来看,可能返回EACCES。
作者: benbenr    时间: 2008-09-13 08:48
shmget(mykey, size, IPC_CREAT | 0666)

权限阿。。。
作者: benbenr    时间: 2008-09-13 08:52
这个KEY值是用
key_t ftok(const char * pathname, int proj_id);

这个函数生成的阿。。。24的KEY还能这么用的,汗。
作者: disheng727    时间: 2008-09-13 09:21
if((shmid=shmget(MYKEY,BUF_SIZE,IPC_CREAT))==-1) 这种方法生成IPC标识符不太好啊。有专门的KEY 生成函数嘛。
作者: jqx55ah    时间: 2008-09-13 13:31
#define IPCKEY 0x111

char path[256];

    sprintf( path, "%s/etc/config.ini", (char*)getenv("HOME") );
    msgid=ftok( path, IPCKEY );


我用这种方法的结果 还是“shmat error!”
作者: jinmiaobis    时间: 2008-09-13 14:21
给你个例子把
int GetMessageQueue(key_t key, int flag)
{
        int imqid=0;

             if (flag == 1)                //创建
             {
                  imqid = msgget(key, IPC_CREAT|0666);
      }
             else                        //获取
             {
                 imqid = msgget(key, 0666);
      }

             if (imqid == -1)
             {
                  return -1;
             }

             return imqid;
}
作者: timespace    时间: 2008-09-13 17:02
推荐UNIX Network Programming Volume 2 Second Edition lnterprocess ommunications by W. Richard Stevens

下面我写个例子,简单的生成者-消费者问题实现,一个程序里用父子进程方式实现生产者和消费者,分开两个进程写原理也类似,为了节省空间就偷个懒啦。共享内存保存数据,Posix基于内存的信号量同步数据访问
#include <stdio.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define PATHNAME "/tmp/.what_the_hell_is_this"

typedef struct Item {
    sem_t full, empty;
    int   data;
} Item;

void sys_err(const char* msg);

int main() {
    key_t    key;
    pid_t    pid;
    int        shmid;
    Item*    addr;

    /* remove a shared memory segment from the system */
    key = ftok(PATHNAME, 1);
    if (key == -1)
        sys_err("ftok");
    shmid = shmget(key, 0, SHM_R|SHM_W);
    shmctl(shmid, IPC_RMID, NULL);
   
    /* create a new shared memory segment */
    shmid = shmget(key, sizeof(Item), IPC_CREAT|IPC_EXCL|SHM_W|SHM_R);
    if (shmid == -1)
        sys_err("shmget");
    addr = (Item*)shmat(shmid, NULL, 0);
    if (addr == (Item*)-1)
        sys_err("shmat");
   
    /* initialize addr */
    sem_init(&addr->full, 1, 0);
    sem_init(&addr->empty, 1, 1);
    shmdt(addr);
   
    pid = fork();
    if (pid > 0) { /* parent for writing */
        shmid = shmget(key, 0, SHM_W);
        if (shmid == -1)
            sys_err("parent shmget");
        addr = (Item*)shmat(shmid, NULL, 0);
        if (addr == (Item*)-1)
            sys_err("parent shmat");
        while (1) {
            sem_wait(&addr->empty);
            fprintf(stdout, "parent: ");
            fscanf(stdin, "%d", &addr->data);
            sem_post(&addr->full);
        }   
    } else if (pid == 0) { /* child for reading */
        shmid = shmget(key, 0, SHM_R);
        if (shmid == -1)
            sys_err("child shmget");
        addr = (Item*)shmat(shmid, NULL, 0);
        if (addr == (Item*)-1)
            sys_err("child shmat");
        while (1) {
            sem_wait(&addr->full);
            fprintf(stdout, "child: %d\n", addr->data);
            sem_post(&addr->empty);
        }   
    } else {
        sys_err("fork");
    }
   
    return 0;
}

void sys_err(const char* msg) {
    perror(msg);
    exit(0);
}



[lgr@localhost lab]$ gcc shm.c -lrt
[lgr@localhost lab]$ touch /tmp/.what_the_hell_is_this
[lgr@localhost lab]$ ./a.out
parent: 13
child: 13
parent: 4567
child: 4567
parent:
作者: benbenr    时间: 2008-09-13 22:39
chao@chao-laptop:~/c-study/cu$ cat shmread.c
#include <stdio.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <errno.h>

#define BUF_SIZE&nbsp;&nbsp;&nbsp;&nbsp;1024
#define MYKEY&nbsp;&nbsp;&nbsp;&nbsp;24

int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;shmid;
&nbsp;&nbsp;&nbsp;&nbsp;char *&nbsp;&nbsp;&nbsp;&nbsp;shmptr;
&nbsp;&nbsp;&nbsp;&nbsp;key_t&nbsp;&nbsp;&nbsp;&nbsp;key;

&nbsp;&nbsp;&nbsp;&nbsp;if (( key = ftok(".", MYKEY)) == -1)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("ftok error!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (( shmid = shmget(key, BUF_SIZE, IPC_CREAT | 0666)) == -1)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("shmget error!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (( shmptr = shmat(shmid, 0, 0)) == (void *)-1)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("shmat error!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;while(1)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("string: %s\n", shmptr);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(*shmptr != '\0')
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmptr++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(3);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}
chao@chao-laptop:~/c-study/cu$ cat shmwrite.c
#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>

#define BUF_SIZE&nbsp;&nbsp;&nbsp;&nbsp;1024
#define&nbsp;&nbsp;&nbsp;&nbsp;MYKEY&nbsp;&nbsp;&nbsp;&nbsp;24
int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;shmid;
&nbsp;&nbsp;&nbsp;&nbsp;char *&nbsp;&nbsp;&nbsp;&nbsp;shmptr;
&nbsp;&nbsp;&nbsp;&nbsp;key_t&nbsp;&nbsp;&nbsp;&nbsp;key;

&nbsp;&nbsp;&nbsp;&nbsp;if(( key = ftok(".", MYKEY)) == -1)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("ftok error\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (( shmid = shmget(key, BUF_SIZE, IPC_CREAT | 0666)) == -1)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("shmget error\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (( shmptr = shmat(shmid, 0, 0)) == (void *)-1)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("shmat error\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;while(1)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("writer: ");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fgets(shmptr, BUF_SIZE, stdin);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(*shmptr != '\n')
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmptr++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*shmptr = '\0';
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//getchar();

&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
}


我也写了一个,是按照LZ的改的。编译好后,开2个终端,在写的地方输入,读的地方就能读到。不输入的话读出来是空的。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2