[英]POSIX in C semaphore with fork and shared memory,
I am trying to do a program with semaphore and fork and shared memory 我正在尝试使用信号量和分叉以及共享内存来做一个程序
the parent suppose to create the shared memory and insert numbers to the buffer print done then the child going to read from shared memory and print the sum of the numbers the program run but only the parent print done but the child does not do any thing, 父级假设要创建共享内存并在完成的缓冲区打印中插入数字,然后子级将从共享内存中读取并打印程序运行的数字之和,但只有父级打印完成,而子级却不做任何事情,
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sys/wait.h>
#include<unistd.h>
#include <sys/shm.h>
char buffer[10];
char *data;
int commNo =0;
key_t key;
int shmid;
char *shrmem;
int mode;
void error(char *msg)
{
perror(msg);
exit(0);
}
int rem[10];
key_t key; /* key to pass to semget() */
key_t key1; /* key to pass to semget() */
key_t key2; /* key to pass to semget() */
key_t key3; /* key to pass to semget() */
int semflg; /* semflg to pass tosemget() */
int nsems; /* nsems to pass to semget() */
int semid; /* return value from semget() */
#define MAX_COUNT 200
#define N 100 /* shared buffer of size 100 */
void ChildProcess(void); /* child process prototype */
void ParentProcess(void); /* parent process prototype */
//things for ftok
char *path = "/tmp";
int id = 'S';
//create sembuf
//struct sembuf{
// ushort sem_num; /* semaphore index in array */
// short sem_op; /* semaphore operation */
// short sem_flg; /* operation flags */
//};
int locksem = 1; /* binary semaphore for locking-unlocking: initiall unlocked : 1 */
int emptysem = 100; /* counting semaphore for empty slots */
int fullsem = 0; /* counting semaphore for filled slots*/
struct sembuf oplock;// = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf oplock;
//oplock.sem_num = 0;
//oplock.sem_op = -1;
//oplock.sem_flg = SEM_UNDO;
struct sembuf opunlock; // = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf opunlock;
//opunlock.sem_num = 0;
//opunlock.sem_op = 1;
//opunlock.sem_flg = SEM_UNDO;
void creatmemory(){
/* make the key: */
if ((key = ftok("/tmp",1)) == -1) {
perror("ftok");
//clientnumber
exit(1);
}
/* connect to (and possibly create) the segment: */
if ((shmid = shmget(key, 15, 0644| IPC_CREAT)) == -1) {
perror("shmget");
exit(1);
}
/* attach to the segment to get a pointer to it: */
data = shmat(shmid, (void *)0, 0);
if (data == (char *)(-1)) {
perror("shmat");
exit(1);
}
}
int main(int argc, char *argv[]){
pid_t pid;
nsems = 1;
//static struct sembuf oplock;
oplock.sem_num = 0;
oplock.sem_op = -1;
oplock.sem_flg = SEM_UNDO;
//static struct sembuf opunlock;
opunlock.sem_num = 0;
opunlock.sem_op = 1;
opunlock.sem_flg = SEM_UNDO;
//to create new one
semflg = IPC_CREAT;
/* Get unique key for semaphore. */
if ((key1 = ftok(path,1)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key2 = ftok(path,2)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key3 = ftok(path,3)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
pid = fork();
if (pid == 0) {
//***************************************************************************************************************
//
int n =0;
while(n < 3){
locksem = semget(key1, nsems, semflg); /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
semop(fullsem,&oplock,1); /* check filled slots */
semop(locksem,&oplock,1); /* lock shared buffer*/
// itx= remove_item();
/* remove an item from buffer */
int i;
for (i =0; i<10; i++){
rem[i] = data[i];}
bzero(buffer,10);
bzero(data,strlen(data));
/* detach from the segment: */
if (shmdt(data) == -1) {
perror("shmdt");
exit(1);
}
semop(locksem,&opunlock,1); /* unlock the buffer */
semop(emptysem,&opunlock,1); /* increment emptysem*/
//consume_item(itx);
int sum = 0;
for(i =0; i<10; i++){
sum += rem[i];}
printf("the sum is:%d \n", sum);
n++;}
}
//consumer();
else
{
creatmemory();
int n =0;
while( n < 3) {
locksem = semget(key1, nsems, semflg); /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
bzero(buffer,10);
int i;
for(i =0; i<10; i++)
buffer[i] = i;
semop(emptysem,&oplock,1); /* check empty slots */
semop(locksem,&oplock,1); /* lock shared buffer*/
/* insert item into the buffer */
strncpy(data, buffer, strlen(buffer));
printf("done \n");
semop(locksem,&opunlock,1); /* unlock the buffer */
semop(fullsem,&opunlock,1); /* increment fullsem*/
sleep(10);
n++;}
}
// producer();
}
Here is a version of the code that actually compiles and links cleanly: 这是实际上可以干净地编译和链接的代码版本:
#define _XOPEN_SOURCE (1) // needed by sys/ipc.h
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h> // exit()
#include <string.h>
#include <strings.h> // bzero())
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/shm.h>
char buffer[10];
char *data;
int commNo =0;
key_t key;
int shmid;
char *shrmem;
int mode;
void error(char *);
int rem[10];
key_t key; /* key to pass to semget() */
key_t key1; /* key to pass to semget() */
key_t key2; /* key to pass to semget() */
key_t key3; /* key to pass to semget() */
int semflg; /* semflg to pass tosemget() */
int nsems; /* nsems to pass to semget() */
int semid; /* return value from semget() */
#define MAX_COUNT 200
#define N 100 /* shared buffer of size 100 */
void creatmemory( void );
//things for ftok
char *path = "/tmp";
int id = 'S';
//create sembuf
//struct sembuf{
// ushort sem_num; /* semaphore index in array */
// short sem_op; /* semaphore operation */
// short sem_flg; /* operation flags */
//};
int locksem = 1; /* binary semaphore for locking-unlocking: initiall unlocked : 1 */
int emptysem = 100; /* counting semaphore for empty slots */
int fullsem = 0; /* counting semaphore for filled slots*/
struct sembuf oplock;// = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf oplock;
//oplock.sem_num = 0;
//oplock.sem_op = -1;
//oplock.sem_flg = SEM_UNDO;
struct sembuf opunlock; // = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf opunlock;
//opunlock.sem_num = 0;
//opunlock.sem_op = 1;
//opunlock.sem_flg = SEM_UNDO;
int main()
{
pid_t pid;
nsems = 1;
//static struct sembuf oplock;
oplock.sem_num = 0;
oplock.sem_op = -1;
oplock.sem_flg = SEM_UNDO;
//static struct sembuf opunlock;
opunlock.sem_num = 0;
opunlock.sem_op = 1;
opunlock.sem_flg = SEM_UNDO;
//to create new one
semflg = IPC_CREAT;
/* Get unique key for semaphore. */
if ((key1 = ftok(path,1)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key2 = ftok(path,2)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key3 = ftok(path,3)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
if( 0 == (pid = fork() ) )
{ // then, child process
int n =0;
for(;n<3;n++)
{
locksem = semget(key1, nsems, semflg); /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
semop(fullsem,&oplock,1); /* check filled slots */
semop(locksem,&oplock,1); /* lock shared buffer*/
// itx= remove_item();
/* remove an item from buffer */
int i = 0;
for (;i<10; i++)
{
rem[i] = data[i];
} // end for
bzero(buffer,10);
bzero(data,strlen(data));
/* detach from the segment: */
if (shmdt(data) == -1)
{
error( "shmdt" );
} // error() does not return
// implied else, shmdt successful
semop(locksem,&opunlock,1); /* unlock the buffer */
semop(emptysem,&opunlock,1); /* increment emptysem*/
//consume_item(itx);
int sum = 0;
for(i =0; i<10; i++)
{
sum += rem[i];
} // end for
printf("the sum is:%d \n", sum);
} // end while
}
else
{ // else parent process
creatmemory();
int n =0;
for(;n<3;n++)
{
locksem = semget(key1, nsems, semflg); /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
bzero(buffer,10);
int i;
for(i =0; i<10; i++)
{
buffer[i] = i;
} // end for
semop(emptysem,&oplock,1); /* check empty slots */
semop(locksem,&oplock,1); /* lock shared buffer*/
/* insert item into the buffer */
strncpy(data, buffer, strlen(buffer));
printf("done \n");
semop(locksem,&opunlock,1); /* unlock the buffer */
semop(fullsem,&opunlock,1); /* increment fullsem*/
sleep(10);
} // end for
} // end if
return(0);
} // end function: main
void creatmemory()
{
/* make the key: */
if ((key = ftok("/tmp",1)) == -1)
{
error( "ftok" ); // error does not return
}
// implied else, ftok successful
/* connect to (and possibly create) the segment: */
if ((shmid = shmget(key, 15, 0644| IPC_CREAT)) == -1)
{
error( "shmget" ); // error does not return
}
// implied else, shmget successful
/* attach to the segment to get a pointer to it: */
data = shmat(shmid, (void *)0, 0);
if (data == (char *)(-1))
{
error( "shmat" ); // error does not return
}
// implied else, shmat successful
} // end function: creatmemory
void error(char *msg)
{
perror(msg);
exit(0);
} // end function: error
I would suggest using a mutex rather than a semaphore for critical code/data protection. 我建议对关键代码/数据保护使用互斥锁而不是信号灯。
BTW: unless destroyed, a semaphore is around forever. 顺便说一句:除非被销毁,否则信号灯将永远存在。
In Linux, they become part of the /proc directory tree. 在Linux中,它们成为/ proc目录树的一部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.