Linux environment programming - ftok () function detailed

  

system to establish IPC communication (such as message queue, shared memory) must specify an ID value. Usually, the id value is obtained by the ftok function. The ftok prototype is as follows: key_t ftok ( char * fname, int id ) fname is the file name you specify (the file must be present and accessible), id is the sub-sequence, although it is int, but only 8 bits are used (0-255). When executed successfully, a key_t value will be returned, otherwise -1 is returned. In a typical UNIX implementation, the index node number of the file is taken out, and the sub-number is added to the return value of key_t. If the inode number of the specified file is 65538, converted to hexadecimal 0x010002, and the ID value you specify is 38, converted to hexadecimal 0x26, the final key_t return value is 0x26010002. The method for querying the index node number of the file is: ls -i The following is the test program: #include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>#define IPCKEY 0x11int main ( void ){ int i=0; for ( i = 1; i < 256; ++ i ) printf( "key = %x\ ", ftok( "/tmp", i ) ); return 0 ;}

After successfully obtaining the key, you can use the key as the key value of the interprocess communication of a certain method, such as the way shmget shares memory.

The function prototype of shmget is

int shmget( key_t, size_t, flag);

After the creation is successful, the descriptor of shared memory is returned. The key_t used in shmget is the

instance generated by ftok:

#include <sys/shm.h>#include <stdio.h>#include < Errno.h>#include <string.h>#include <stdlib.h>

#define SIZE 1024

extern int errno;

int main() {int shmid;char *shmptr;

//Create shared memory if((shmid = shmget(IPC_PRIVATE, SIZE, 0600)) < 0) { printf("shmget error:%s\ " , strerror(errno)); return -1; }

//Connect shared memory to an available address

if((shmptr = (char*)shmat(shmid, 0, 0 )) == (void*)-1){ printf("shmat error:%s\ ", strerror(errno)); return -1;}memcpy(shmptr, "hello world", sizeof(" Hello world"));printf("share memory from %lx to %lx, content:%s\ ",(unsigned long)shmptr, (unsigned long)(shmptr + SIZE), shmptr);

//Remove shared memory if((shmctl(shmid, IPC_RMID, 0) < 0)){ printf("shmctl error:%s\ ", strerror(errno)); return -1;}}< Br>

Multi-process Shared memory situation:

#include <sys/shm.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib. h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>

#define SIZE 1024

extern int errno;

int main(){int shmid;char *shmptr;key_t key;pid_t pid;

if((pid = fork()) < 0){ printf("fork error :%s\ ", strerror(errno)); return -1; }else if(pid == 0) { sleep(2); if((key = ftok("/dev/null", 1)) < 0) { printf("ftok error:%s\ ", strerror(errno)); return -1; }if((shmid = shmget(key, SIZE, 0600)) < 0){ printf( "shmget error:%s\ ", strerror(errno)); exit(-1); }

if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1){ printf("shmat error:%s\ ", strerror(errno)); exit(-1);}//memcpy(shmptr, "hello world", sizeof(" Hello world")); printf("child:pid is %d,share memory from % Lx to %lx, content:%s\ ", getpid(), (unsigned long)shmptr, (unsigned long)(shmptr + SIZE), shmptr);printf("child process sleep 2 seconds\ "); Sleep(2);if((shmctl(shmid, IPC_RMID, 0) < 0)){ printf("shmctl error:%s\ ", strerror(errno)); exit(-1);} exit( 0); } //parent else { if((key = ftok("/dev/null", 1)) < 0) { printf("ftok error:%s\ ", strerror(errno)) ; return -1; }if((shmid = shmget(key, SIZE, 0600| IPC_CREAT| IPC_EXCL)) < 0)

{ printf("shmget error:%s\ ", strerror(errno)); exit(-1); }

if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1){ printf("shmat error:%s\ ", strerror(errno)); exit(-1);} Memcpy(shmptr, "hello world", sizeof("hello world"));printf("parent:pid is %d,share memory from %lx to %lx, content:%s\ ",getpid( ), (unsigned long) shmptr, (unsigned long)(shmptr + SIZE), shmptr);printf("parent process sleep 2 seconds\ ");sleep(2);if((shmctl(shmid, IPC_RMID, 0 ) < 0)){ printf("shmctl error:%s\ ", strerror(errno)); exit(-1);} }

waitpid(pid,NULL,0);exit (0);}

The output is:


shmctl(shmid, IPC_RMID, 0) is used to remove the congratulatory segment from the system. Because each shared bucket has a connection count (shm_nattch in the shmid_ds structure), the bucket will not actually be deleted unless the last process using the segment terminates with the segment.

Copyright © Windows knowledge All Rights Reserved