发新话题
打印

共享内存权限问题

共享内存权限问题

小弟在使用共享内存时,试图用多个用户同时共享其中一个用户创建的共享内存,结果没有得逞,总是shmget error或permission deny。还望各位高人指点,不胜感激。* G8 j, p* a: x  E# L' u
4 D, S2 M2 u; F
[已被 wenfeng 编辑过, 在 2001-07-13  11:44]      

TOP

一个用户进程不能存取别的用户进程的内存空间。这是linux的机制。$ H7 [! ~6 E8 a9 E( H* R% h
但可以通过/proc文件来共享。      
庄子曰:“?鱼出游从容,是鱼之乐也。” 惠子曰:“子非鱼,安知鱼之乐?” 庄子曰:“子非我,安知我不知鱼之乐?” 惠子曰:“我非子,固不知子矣;子,固非鱼也,子之不知鱼之乐,全矣。” 庄子曰:“请循其本。子曰‘汝安知鱼乐’云者,既已知吾知之,而问我;我知之濠上也。”

TOP

这位大哥,能否详细赐教如何用/proc文件来多用户共享内存      

TOP

不知道你要共享内存空间的目的是什么,如果是多个同属于一个父进程的子进程要共享内存空间,我建议你把程序改成多线程的,这样多线程的当然就可以对一个用户空间进行存取。如果一定要多个进程共享内存空间,用/proc文件虽然可以实现,但是相当麻烦,而且主要是LKM编程。; g1 s1 U2 u8 t' e  p8 ?* M
你可以先看看这个程序,
& {3 C6 }- H- R, f' U0 ^/* procfs.c -  create a "file" in /proc - M- a; M" U2 W4 x; ]
* Copyright (C) 1998-1999 by Ori Pomerantz
# k9 y9 [* I, P6 _2 K9 w */
& b' T  y! G4 N( U1 h% ?+ C1 A: C, r7 S" |) ~7 U
) L4 A" j# Z9 r6 [: X! T+ Q
/* The necessary header files */
. n' K$ Y6 a9 V& @( T5 D4 |
" U, c- D6 i8 y3 X2 Q* x/* Standard in kernel modules */
- {1 _" L8 L6 ?0 _#include <linux/kernel.h>   /* We're doing kernel work */0 K; k5 a  G- y
#include <linux/module.h>   /* Specifically, a module */
! |1 |( V" `  p2 z( C) N4 z  v6 v  d. I# n
/* Deal with CONFIG_MODVERSIONS */
% N2 ^; c9 c7 i$ ]- k: U, y#if CONFIG_MODVERSIONS==1
! `0 `5 c, D/ f6 ^, p! T' d#define MODVERSIONS
' D# u* n% g/ Q& H) D- S% y: h#include <linux/modversions.h>
1 J8 D) d7 {3 c: P* L#endif        # T( {0 M# T, c7 n
2 E, A2 @# `8 T' M
; P- t( Y! ]3 Q
/* Necessary because we use the proc fs */6 @! H4 ^" ]4 T, v3 @  B
#include <linux/proc_fs.h>
. X+ m6 T: G  d- y8 U
' k/ n- _, K5 Q/ ~/ G
2 k$ l" c% w4 r$ w1 C/* In 2.2.3 /usr/include/linux/version.h includes a
/ m9 E! y5 S% ]" a' a- B * macro for this, but 2.0.35 doesn't - so I add it
" u' m. T/ F, x! E8 X3 x7 s9 A  K8 s * here if necessary. */. G4 e- d8 l; w
#ifndef KERNEL_VERSION
1 F2 W* [4 W8 X. @: G#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
+ M  T% @, N+ H* r1 Y% V+ E; r8 w#endif9 l; S: B$ H5 ^9 `: |

, M6 A6 i! D) v3 V: q
& U; i  E9 S9 r( _, B4 Q; w1 K2 u- c; O8 X( U7 U) x) B- q' O
/* Put data into the proc fs file.5 i9 h4 C  i5 v7 u  b0 p

7 y5 U  ]6 R. S6 T3 {0 u  P   Arguments% S: D8 J. l$ i! `3 V
   =========
( Z, @$ a. S2 P% j2 i& z& A   1. The buffer where the data is to be inserted, if
1 m  L$ k" U" c( |" o      you decide to use it.: _7 d+ K  O9 f: Z5 J. w) s
   2. A pointer to a pointer to characters. This is / x  @  E, p* \( ]! o
      useful if you don't want to use the buffer ) t$ v3 b: r( f# K; c
      allocated by the kernel.7 w) y! N+ O7 b# h
   3. The current position in the file. ! ]; f( B  N7 O5 T
   4. The size of the buffer in the first argument.  
6 g! t& n8 J( ^- y- Q, c0 p   5. Zero (for future use?).
3 D  M0 b  A$ Q+ I
5 c9 k& L! q. K' u8 K" j
* P$ o+ }2 h7 P- I: Z   Usage and Return Value7 V1 j% n# G" Y2 X. d
   ======================  {4 T& j5 |$ P8 R, Z8 n
   If you use your own buffer, like I do, put its " P5 S$ [: s( N' p
   location in the second argument and return the 0 f& U7 h( g: m- x5 x
   number of bytes used in the buffer.
6 l( b, A" }7 V/ ~/ y9 J) S( `( H' r6 u  J- u- ^' u
   A return value of zero means you have no further " u' ~5 R& |+ ?/ P7 B
   information at this time (end of file). A negative
8 K( P% ]" @/ R4 U   return value is an error condition.. n6 }" v3 d1 y+ z
   $ j+ Q  e7 L5 r

* a: O; x) W3 I, @7 p   For More Information9 |7 l0 C* N( V
   ====================
% x) i- {3 {  U+ S% C/ u: O   The way I discovered what to do with this function
3 P3 ?& j) W. I- b   wasn't by reading documentation, but by reading the
; M* @8 S% X# W5 C+ k2 }: N2 s   code which used it. I just looked to see what uses 2 c9 C; D8 p3 C. F
   the get_info field of proc_dir_entry struct (I used a ( n; c1 f4 c" ~5 [4 M8 V9 Z: j0 t
   combination of find and grep, if you're interested), + l' ^7 \  e. f5 N& R9 ^
   and I saw that  it is used in /fs/proc/array.c.
% C$ D; U$ `9 \' Q6 A0 v
4 l% p% a* O) Q, o& n+ w   If something is unknown about the kernel, this is 9 T& \! S# t& i% @4 K7 w
   usually the way to go. In Linux we have the great
5 v2 E$ d$ F: l+ c6 I1 \   advantage of having the kernel source code for
$ ?  y/ Z) Y' R( Y1 w& j   free - use it.
7 C# |+ D2 D. ] */& @, V7 _6 a; r
int procfile_read(char *buffer,
9 q- q; \0 X2 D1 |9 U# @+ I                  char **buffer_location,
2 Z: T* V! o% C; `% Z" M                  off_t offset,
$ D/ q) L& W- @0 I& n" w- d" [                  int buffer_length, 1 s1 u7 T( \/ v
                  int zero), F/ C9 L: N, `/ q6 k5 q
{) d0 t. d) p, f5 i* H, X4 R! _
  int len;  /* The number of bytes actually used */
) X9 u) k! H1 {0 t" \" f7 i! m6 w7 I- K7 R! L* B  K
  /* This is static so it will still be in memory
7 D+ _4 G% H+ ?   * when we leave this function */
  E7 N! Z5 q# H& p  static char my_buffer[80];  . c" S, q9 L9 [! g* `" Q

0 k5 ~4 ]+ m+ K8 j3 r- a  static int count = 1;) M9 _4 y! {' T4 Z0 r, X0 l
, T3 b! H+ b/ N/ g
  /* We give all of our information in one go, so if the
- g( E% m& t# k1 ^- w$ h& |2 v   * user asks us if we have more information the * f; n& U0 m* o; b9 K0 _
   * answer should always be no. * ]; Y) [- o6 x( ?( r  F0 Z5 z; f
   *
3 K5 z0 z2 f4 g/ t" q   * This is important because the standard read * T& U$ d: K- m0 r/ P. H  u/ j7 ]! {6 N
   * function from the library would continue to issue
. v9 ]* R. W$ E% |: t0 c* Z   * the read system call until the kernel replies2 O: e1 ^* B) `* ~
   * that it has no more information, or until its % B9 b  H7 Y. a. C
   * buffer is filled.
5 y& e9 f( Z9 m   */
" s' x" n5 x9 R# k$ U  if (offset > 0)- c' B4 Z! E$ ]' y, [
    return 0;
' y0 r9 E) X" C5 `. ~7 d9 w6 v
9 _3 g5 A: A) k" Z3 ]  /* Fill the buffer and get its length */  ^+ ^, K, R1 w9 J% c; _2 W* K
  len = sprintf(my_buffer, ' c; W; I  h/ A% P% R# `  F
    "For the %d%s time, go away!\n", count,0 a& P6 v8 M) ~% \# Z
    (count % 100 > 10 && count % 100 < 14) ? "th" :
( u. r! j- M4 S& M+ W- N6 ~3 B      (count % 10 == 1) ? "st" :
: Z7 b/ U- F  T. }  g        (count % 10 == 2) ? "nd" :
# P& c- h, Q' `) A          (count % 10 == 3) ? "rd" : "th" );
: L. U0 [$ q) m* k0 q  count++;
) I5 u' Q! T7 |1 A, e( b' v) R9 T! _0 b) J: K9 n; v
  /* Tell the function which called us where the
9 U; J" m; }1 g6 b5 n( K7 l/ o   * buffer is */* c+ h% P6 f. G: c
  *buffer_location = my_buffer;
1 ]( X! u& W2 ^1 L2 Z' ^: K6 ^" c6 S. M3 q
  /* Return the length */
  F$ R  t* q! m" ~& o  return len;
- s6 C. n( I$ ?4 ]}
) m+ d) C- ?5 h3 N% o4 R6 D% Q  P& ~' Z0 C, W$ u

6 o4 T' e+ n6 _, ?" ?# @struct proc_dir_entry Our_Proc_File =
: G. i% d& f5 s  {
/ w8 n6 r, Q- _2 D# o! G$ x    0, /* Inode number - ignore, it will be filled by 4 H/ Z$ ^0 ^" G
        * proc_register[_dynamic] */
$ D& |: P& _# l( M    4, /* Length of the file name */% Q. t: S( X4 w3 i$ x1 O, w0 \# M
    "test", /* The file name */5 t- o+ ?! g4 ~9 _* {6 i" ]* _, `" ?( _
    S_IFREG | S_IRUGO, /* File mode - this is a regular + X; j, {* G( P) z/ p( Y  m1 [
                        * file which can be read by its
0 q' Y1 b8 u: G3 T5 _0 X  A                        * owner, its group, and everybody
! m; r' k0 y2 {4 M' @; c                        * else */4 |9 \) B2 A* |7 X
    1,        /* Number of links (directories where the
+ k$ X# t: [' D, `& a( x% K         * file is referenced) */
% o- L2 @2 D* Z+ q6 S5 Z6 C    0, 0,  /* The uid and gid for the file - we give it
, p- g' ^8 T$ t6 R  t            * to root */
. C* S, E* N& w8 F, H* |& D/ }    80, /* The size of the file reported by ls. */
( u1 ]: o+ |* t1 ]    NULL, /* functions which can be done on the inode
- ^+ }# t5 [2 R: E, s           * (linking, removing, etc.) - we don't ; a9 i, s* F1 L- R& s
           * support any. */( K: l$ M. n2 D* E
    procfile_read, /* The read function for this file,
+ D5 T8 A7 O0 _1 d2 T1 f                    * the function called when somebody
6 ^4 U' [4 Q+ E+ O# j8 p                    * tries to read something from it. */: T/ W4 l- K# R5 S
    NULL /* We could have here a function to fill the 4 q* |* {' d8 E0 m! B2 ^# R/ x% K
          * file's inode, to enable us to play with ( c7 f( Q) }- d3 c7 ~5 ]( `2 N  n/ S
          * permissions, ownership, etc. */! {) o. F0 z* O
  };
3 m& ]2 t, |6 n8 k$ G
( _: R: h% g2 n; G4 G
2 ]% M' i" e2 g! P# c. |
- d& s; w" I0 P# s" `
' D% |5 q/ }+ M* K3 |
; I$ M7 H) M$ i$ R# k6 N/* Initialize the module - register the proc file */" R( D1 X5 A6 p- _
int init_module()
  g: l9 n* X( V4 g{
/ s. I, V' D& k2 l# b  /* Success if proc_register[_dynamic] is a success, ) |1 H. x. D7 s; i* r) f# d
   * failure otherwise. */
2 J  a+ q* q8 q* Y2 t3 u6 T#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0); v+ [3 {) X, H# N6 Y
  /* In version 2.2, proc_register assign a dynamic
# h3 p, `* a) m   * inode number automatically if it is zero in the 3 I5 K; B. Z! m$ x: Z0 X4 H
   * structure , so there's no more need for # p! f0 f8 P  L9 m+ k( n
   * proc_register_dynamic" U8 ^4 p+ [+ V# C8 w( d5 X! d
   */
" t+ X3 L; m. F+ t0 ~  return proc_register(&proc_root, &Our_Proc_File);
: a4 [& o* @# s, g#else
+ y( g0 f% [& T, u, s9 ?" I. ~  return proc_register_dynamic(&proc_root, &Our_Proc_File);
+ e6 g0 f2 f$ h  ~3 Z' \9 D4 |#endif
2 r0 s; V/ X8 B% O! F/ L
; l/ y. T* w/ ~8 S  /* proc_root is the root directory for the proc
  l* ]' y1 N5 E/ l- m* `   * fs (/proc). This is where we want our file to be ( N  b4 W9 @$ j& m
   * located. # B0 m) w0 j$ t9 M# v7 }
   */, u+ b$ @5 O; G3 g3 P: y) V- f- T% L
}+ w( D. ]/ U- X3 v; _2 T" g; C$ X
5 P: \$ j& M  y  A* t$ N3 P

3 u) I9 v* ?& r& C: w: i% ~/* Cleanup - unregister our file from /proc */
. p$ l1 h+ k( Y0 Nvoid cleanup_module()( F7 ]2 R3 j5 F0 z7 l
{
+ z4 Q! u( @6 m% z* ]" d0 R. X& ~  proc_unregister(&proc_root, Our_Proc_File.low_ino);2 i' y. C/ R; A9 y: C% c- p/ W# x
}      
庄子曰:“?鱼出游从容,是鱼之乐也。” 惠子曰:“子非鱼,安知鱼之乐?” 庄子曰:“子非我,安知我不知鱼之乐?” 惠子曰:“我非子,固不知子矣;子,固非鱼也,子之不知鱼之乐,全矣。” 庄子曰:“请循其本。子曰‘汝安知鱼乐’云者,既已知吾知之,而问我;我知之濠上也。”

TOP

另外我刚刚发现linux中有多个进程共享内存池的机制。7 n% `# \% g+ u+ c2 {
你可以用 ‘man mpool’ 来查看帮助。      
庄子曰:“?鱼出游从容,是鱼之乐也。” 惠子曰:“子非鱼,安知鱼之乐?” 庄子曰:“子非我,安知我不知鱼之乐?” 惠子曰:“我非子,固不知子矣;子,固非鱼也,子之不知鱼之乐,全矣。” 庄子曰:“请循其本。子曰‘汝安知鱼乐’云者,既已知吾知之,而问我;我知之濠上也。”

TOP

多谢赐教,希望能经常探讨。      

TOP

发新话题