发新话题
打印

共享内存权限问题

共享内存权限问题

小弟在使用共享内存时,试图用多个用户同时共享其中一个用户创建的共享内存,结果没有得逞,总是shmget error或permission deny。还望各位高人指点,不胜感激。  \+ z% z8 |1 |+ @0 k) J2 j
, x$ r4 y. a( [/ t* p, S! @4 j
[已被 wenfeng 编辑过, 在 2001-07-13  11:44]      

TOP

一个用户进程不能存取别的用户进程的内存空间。这是linux的机制。
' M  l4 z9 }8 B& ^3 W! ~但可以通过/proc文件来共享。      
庄子曰:“?鱼出游从容,是鱼之乐也。” 惠子曰:“子非鱼,安知鱼之乐?” 庄子曰:“子非我,安知我不知鱼之乐?” 惠子曰:“我非子,固不知子矣;子,固非鱼也,子之不知鱼之乐,全矣。” 庄子曰:“请循其本。子曰‘汝安知鱼乐’云者,既已知吾知之,而问我;我知之濠上也。”

TOP

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

TOP

不知道你要共享内存空间的目的是什么,如果是多个同属于一个父进程的子进程要共享内存空间,我建议你把程序改成多线程的,这样多线程的当然就可以对一个用户空间进行存取。如果一定要多个进程共享内存空间,用/proc文件虽然可以实现,但是相当麻烦,而且主要是LKM编程。
4 s. d$ b, ~: {& @# j你可以先看看这个程序,
  X0 H% S3 d0 `/* procfs.c -  create a "file" in /proc ( U2 a+ |; @' z8 C; H7 o
* Copyright (C) 1998-1999 by Ori Pomerantz
0 O3 x7 C" u1 t0 ^9 x' Q, ?5 b */
5 Q% e( I6 |% O* N
! Z" I) [& ?" z2 c# B# \! f
. R8 _3 d( q: \6 Z  S% \/* The necessary header files */6 a( J+ m" p6 z4 k

' M' v& F8 \1 a, S0 }/* Standard in kernel modules */6 z3 h1 j/ n. I* F- @. v0 N
#include <linux/kernel.h>   /* We're doing kernel work */
- {9 Q1 O  L4 [9 x0 v; U! A#include <linux/module.h>   /* Specifically, a module */* _( b- ~# a7 F4 y

5 \4 B1 x* i5 ?' }6 ]7 {1 [" c. M/* Deal with CONFIG_MODVERSIONS */
4 O4 f% L% e8 Q#if CONFIG_MODVERSIONS==1, c$ J! k2 I/ m
#define MODVERSIONS( t& d' h" S, r0 p
#include <linux/modversions.h>
$ v. x. ]3 i9 U0 w; t#endif        
4 O1 m/ y" u  D% x
2 I9 u! A" N+ I" m* Y6 s) f$ b9 u
7 s& Q7 `0 A5 r( J; y; J6 n/* Necessary because we use the proc fs */2 u( B* p2 s$ m
#include <linux/proc_fs.h>
4 G' U$ w8 ?8 F1 G6 G' w* N4 o9 f: d7 ]3 j

  o, a) I# `/ k& x/* In 2.2.3 /usr/include/linux/version.h includes a
+ j4 I7 _6 Y7 a. ~2 G/ ]( k * macro for this, but 2.0.35 doesn't - so I add it
- o9 ?# D0 C( Q6 ^% v * here if necessary. */
9 T: A/ l5 p5 Z% V: J& ?9 C#ifndef KERNEL_VERSION: U5 P: X+ G2 B  }1 Y
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)): W8 g' H5 O; _; K
#endif
2 N" w& }% s8 y4 b0 T- u, M' B8 b* T! m8 ?1 v* W8 F

: O2 Q" {) z4 v2 z1 ^( _4 n. N, d! U
/* Put data into the proc fs file., |8 j+ i. L3 c6 e1 n

. H, m+ U7 ?; y1 n5 u' D   Arguments
6 }. D, z3 X7 U( V   =========# C" i2 C2 \3 \0 O4 V
   1. The buffer where the data is to be inserted, if
% `' |* R' E( c- y      you decide to use it.
5 |, G' V1 B+ g. N   2. A pointer to a pointer to characters. This is # e/ G' T0 m9 i
      useful if you don't want to use the buffer
  _/ w( T# I1 O/ e5 m7 ]      allocated by the kernel.
, @/ [8 k* i% v. q  _   3. The current position in the file.
% e* X' P3 V! z8 L, `3 W# B  \  I   4. The size of the buffer in the first argument.  " b8 a; }" H& ~0 B( N
   5. Zero (for future use?).9 |% R- V) h/ C$ S7 ~

* l" J6 a4 b8 u. w0 ^. J3 o: p; a/ c% j  g/ ~& y/ k7 T8 j; H
   Usage and Return Value
, w4 G/ F2 D8 q) h+ o6 Y$ z; V   ======================
; ~1 Z. f6 w: F; H5 c( g   If you use your own buffer, like I do, put its
4 j7 e' F( x% A% D* N+ ^   location in the second argument and return the
. p" [( @+ D" y' g4 \* M   number of bytes used in the buffer.3 N2 `- {# O6 X6 x1 _

1 y( @! @; d0 @" G: ?   A return value of zero means you have no further
; z9 o6 h+ Y, L) Q* _1 t   information at this time (end of file). A negative . H: k, a0 t7 `' N" y7 N
   return value is an error condition.6 D. |) C$ V5 l. D# U
   
" Q9 g' n0 t3 w1 t" M
9 j5 I! B% y: i7 Q4 A1 l   For More Information
7 M" n5 @- h( Z3 w   ====================
2 a( I: y' {6 }2 s   The way I discovered what to do with this function : j( h: }; P9 p
   wasn't by reading documentation, but by reading the
  ~  y6 D4 U, j8 Q/ F   code which used it. I just looked to see what uses 1 P" e( M  b  V1 `" A
   the get_info field of proc_dir_entry struct (I used a
& V: S( G! S  _   combination of find and grep, if you're interested),
4 ?, x% s2 l; }4 \, N* u   and I saw that  it is used in /fs/proc/array.c.( G1 F* o+ u2 W- ^, m

* A$ L4 Q+ ~& F$ v% N$ ?* G; A5 r9 X   If something is unknown about the kernel, this is 4 @" K1 x" x. `: |& x, F% c
   usually the way to go. In Linux we have the great
5 n2 ?6 `9 v/ q2 H6 E   advantage of having the kernel source code for 4 _% K0 m- i' H
   free - use it.! l/ \3 G! ~/ a( o
*/
* [) A( c* k; H! Qint procfile_read(char *buffer, 9 e3 b  ]! M3 z! W2 w- X  x
                  char **buffer_location,
1 A+ Y4 S4 x3 V- ?* g1 E, s                  off_t offset,
* l5 M6 a: B. L: P) X& n                  int buffer_length, 6 _  {) g1 }9 L- j$ h! L7 H. C
                  int zero)
5 @# C& z  ^; c2 F{
9 G2 k! A1 n* E3 R1 F) }  int len;  /* The number of bytes actually used */
3 a6 |1 F+ R2 D) s0 c& j% W. M4 u% S9 f. P* c% [1 J: t
  /* This is static so it will still be in memory
0 ]' A. O' i8 {+ }& i4 ^   * when we leave this function */
3 u% a" n, `& `5 v  Z$ c  static char my_buffer[80];  . s( b6 P, `$ J, D  o

. \! w8 x4 ~& E2 Y  J  static int count = 1;
4 g7 l  n$ X. Q# P$ R  `
: G, T" y- m4 R( i  k6 m  /* We give all of our information in one go, so if the $ ]" L  t0 j' u# H7 [( ]2 ]$ Q5 ]
   * user asks us if we have more information the
" U1 S) M# K1 g! }* g+ u& _3 s   * answer should always be no.
/ u# q' ]% b+ Z9 K5 t   *
) @  `9 D) w- \4 K' p! ]7 M  f2 j, k& I$ N   * This is important because the standard read   ^5 `: N2 D3 C
   * function from the library would continue to issue 0 a; q- q4 L) Y1 e% k: e/ |
   * the read system call until the kernel replies* _. c2 k5 B  w: T* Z
   * that it has no more information, or until its & d$ Z. I) r3 A3 e
   * buffer is filled.4 W5 G" O6 G/ n% P4 \$ M7 F
   */
1 g  |9 M! l: ^; g% W& c1 Y3 R  if (offset > 0)
# ]7 j7 i# ~+ ?    return 0;
; D, B  e! c# y3 z4 g
, I/ @  y! h# M' l3 @" r- ?  /* Fill the buffer and get its length */
3 k* p% P+ R4 Y: N! \( B0 x2 A  len = sprintf(my_buffer,
+ h7 v. O9 I& E- d; n  i! ]0 ~    "For the %d%s time, go away!\n", count,
& C' [% E$ j1 c    (count % 100 > 10 && count % 100 < 14) ? "th" : . y5 b. {0 J0 l1 G& k
      (count % 10 == 1) ? "st" :+ G% x' ^8 r6 W+ ^/ ^. Z
        (count % 10 == 2) ? "nd" :
- A9 z; f/ ^4 m' d$ e- n7 k          (count % 10 == 3) ? "rd" : "th" );) Q2 _+ K3 b" M" b
  count++;
$ S6 d3 ^9 @/ A9 E! f, y1 T# c+ _$ v5 A7 h  }
  /* Tell the function which called us where the , j/ ?/ X5 C4 e% N$ I
   * buffer is */# U1 A) g2 f& e2 x
  *buffer_location = my_buffer;
* B  l9 q! P* n
$ P1 b# p6 y; P3 X  z3 z! [2 \( _  /* Return the length */
' d5 u  v0 U4 i- _& O: o  return len;
5 Y' {6 n, g# ^1 f}
3 j* S& M$ D4 t+ x* ^" |7 G2 ?0 c' @# G
- \5 _8 [& B; @2 Z$ `
struct proc_dir_entry Our_Proc_File = : h3 p( j# G3 A" {
  {0 A  |1 V: {7 y. Q
    0, /* Inode number - ignore, it will be filled by
  y6 H# p! m  o" j0 Y7 \        * proc_register[_dynamic] */" I) a- U% ?* I  a! s6 H0 `
    4, /* Length of the file name */
1 \& l( o3 @2 G4 m( i    "test", /* The file name *// Z/ D# @7 p( @. T
    S_IFREG | S_IRUGO, /* File mode - this is a regular 7 s4 F7 A" i, O$ a6 O
                        * file which can be read by its 4 O! r3 ]) X7 V6 P; n( Y
                        * owner, its group, and everybody
* u  r7 v  f5 T0 ~/ K, m7 D                        * else */
7 ]% B- v1 H6 U' x! r5 E    1,        /* Number of links (directories where the
4 W4 `3 M) ~% F4 R' y9 B& J$ s         * file is referenced) */6 _' Q$ l+ H' L. t/ G+ Y6 M( f# l
    0, 0,  /* The uid and gid for the file - we give it 8 t. U' w9 c$ U' J
            * to root */
5 l$ ^' H& G1 O& q3 X) U    80, /* The size of the file reported by ls. */3 s  r" W" E& n! |7 ~
    NULL, /* functions which can be done on the inode ! z  J; F1 C$ L4 b$ q4 g4 U. u
           * (linking, removing, etc.) - we don't ( t  l! b) u9 x2 V/ `
           * support any. */, V/ F) u  X0 f) L
    procfile_read, /* The read function for this file, $ w+ i) j: E. p! P# c: M8 v  S
                    * the function called when somebody
5 j- M5 k1 l8 h; v" t# I                    * tries to read something from it. */
. [' V. S: [( [! j8 Y/ `    NULL /* We could have here a function to fill the
( F+ Q" w" v$ s5 A. Q9 h          * file's inode, to enable us to play with 4 E# m  O6 l) S4 ]* e
          * permissions, ownership, etc. */* f8 R7 Q) P) ~
  };
% r" u& N# n! S3 X! l' H4 u: [. N, k6 d
9 F5 G. S1 A! F3 {

# L/ r0 Z* C3 @- I
7 `! U% }8 N, i6 o7 m$ I+ j# I: \8 k9 `7 ]( ?4 l
/* Initialize the module - register the proc file */
' I5 H' i- b( M* a6 a% Cint init_module()
" m3 T7 |2 F% R{/ i" T; \; J8 [
  /* Success if proc_register[_dynamic] is a success, / Y* i6 O- T5 m: F1 |
   * failure otherwise. */; Q) p( P3 y( ^. u" Y
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)/ R3 o5 K: X# R0 C: y8 j
  /* In version 2.2, proc_register assign a dynamic   l. R3 n/ O/ k' E7 E; M0 r
   * inode number automatically if it is zero in the ! {- R5 A# Y) m: L8 a$ \
   * structure , so there's no more need for % N! o# |3 r+ M2 }
   * proc_register_dynamic
& N- R, g: p% |7 v/ D& ?; P5 D+ l   */" ^1 P  s& Q$ w
  return proc_register(&proc_root, &Our_Proc_File);
1 P) N: c; P; E! ?7 D. G#else
+ J9 Z7 {/ E, ~* Y9 w  Q& K* A  return proc_register_dynamic(&proc_root, &Our_Proc_File);
$ A% M/ @7 j# u# C#endif9 W& R' n5 V9 ~- ?
$ t+ [5 p! f; b$ B7 h# @* e" R$ f, r
  /* proc_root is the root directory for the proc
* k# v1 X) T1 Q8 y   * fs (/proc). This is where we want our file to be
; K2 p* E, ?$ W$ T) f   * located. 4 W; z3 C# X% m9 y9 }9 S2 z
   */
1 _/ J& i/ i, c5 E}
# X7 X; @6 M6 g- P" D$ K$ f% e; e0 m! Q" H) `

9 F+ H, m5 t# N& ^/* Cleanup - unregister our file from /proc */) l- ~' h, ^  M: n
void cleanup_module()
; R: o7 J  b7 c) L5 v5 F. U{# j# v( Z0 y* E9 N4 \
  proc_unregister(&proc_root, Our_Proc_File.low_ino);. y; P: v* c5 g* m
}      
庄子曰:“?鱼出游从容,是鱼之乐也。” 惠子曰:“子非鱼,安知鱼之乐?” 庄子曰:“子非我,安知我不知鱼之乐?” 惠子曰:“我非子,固不知子矣;子,固非鱼也,子之不知鱼之乐,全矣。” 庄子曰:“请循其本。子曰‘汝安知鱼乐’云者,既已知吾知之,而问我;我知之濠上也。”

TOP

另外我刚刚发现linux中有多个进程共享内存池的机制。
1 @& I: S) Y9 C! K+ @你可以用 ‘man mpool’ 来查看帮助。      
庄子曰:“?鱼出游从容,是鱼之乐也。” 惠子曰:“子非鱼,安知鱼之乐?” 庄子曰:“子非我,安知我不知鱼之乐?” 惠子曰:“我非子,固不知子矣;子,固非鱼也,子之不知鱼之乐,全矣。” 庄子曰:“请循其本。子曰‘汝安知鱼乐’云者,既已知吾知之,而问我;我知之濠上也。”

TOP

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

TOP

发新话题