![]() |
| | #1 |
| Registered User Join Date: Nov 2005 Location: Alpine, TX
Posts: 31
| semaphores In my program I am using multiple semaphores getting them using: Code: semid = semget(IPC_PRIVATE, 4, 0600 | IPC_CREAT);
/* Initialize values for the 4 semaphores */
semctl(semid, 0, SETVAL, 0);
semctl(semid, 1, SETVAL, ITEM_SIZE * 10);
semctl(semid, 2, SETVAL, 0);
semctl(semid, 3, SETVAL, 0);
|
| Dr Spud is offline | |
| | #2 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| I think you need to use sem_open() http://www.opengroup.org/pubs/online.../sem_open.html You won't be able to get four semaphores in one call with this method, but I'm sure you can work around that. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #3 |
| Registered User Join Date: Nov 2005 Location: Alpine, TX
Posts: 31
| okay so I think I got the name thing figured out thx for the reply but im thinking because I used <sys/sem.h> instead I have to go a different route. Now my program hangs up and neither process will run. heres my code, any ideas why this is happening? Code: #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#define ITEM_SIZE 4096
/* define semaphores within the set */
#define SEM_FULL 0
#define SEM_EMPTY 1
#define SEM_LAST_TRANS_SIZE 2
#define SEM_TERMINATED 3
char input_line[50]; /* gather file names from user */
char output_line[50];
char items[ITEM_SIZE];
char buffer[ITEM_SIZE * 10]; /* array of 10 items */
FILE *in_file; /* input = file to read; output = file to write */
FILE *out_file;
union semun
{
int val;
struct semid_ds *buf;
ushort *array;
} seminfo;
struct sembuf Wait_Empty={SEM_EMPTY, -1, 0};
struct sembuf Signal_Empty={SEM_EMPTY, 1, 0};
struct sembuf Wait_Full={SEM_FULL, -1, 0};
struct sembuf Signal_Full={SEM_FULL, 1, 0};
int main(){
int pid;
int terminated_val;
int read_size; /* number of bytes on last read */
/* gather shared memory space */
int shmid;
char * shm_addr;
shmid = shmget(IPC_PRIVATE, ITEM_SIZE * 10, IPC_CREAT); /* creat sh memory */
shm_addr = shmat(shmid, NULL, 0); /* attach sh memory */
/* get the 4 semaphores to be used */
int semid;
semid = semget(IPC_PRIVATE, 4, 0600 | IPC_CREAT);
/* Initialize values for the 4 semaphores */
semctl(semid, SEM_FULL, SETVAL, 0);
semctl(semid, SEM_EMPTY, SETVAL, ITEM_SIZE * 10);
semctl(semid, SEM_LAST_TRANS_SIZE, SETVAL, 0);
semctl(semid, SEM_TERMINATED, SETVAL, 0);
/* gather the input file for the child to read from the user */
fprintf(stderr, "Enter the file name to be copied:");
fgets(input_line, sizeof(input_line), stdin);
if(input_line[strlen(input_line)-1] == '\n') input_line[strlen(input_line)-1] = 0;
/* gather the output file for the parent to put the copy in */
fprintf(stderr, "Enter the file name to be written:");
fgets(output_line, sizeof(output_line), stdin);
if(output_line[strlen(output_line)-1] == '\n') output_line[strlen(output_line)-1] = 0;
/* fork and cross fingers */
pid = fork();
/* parent process responsible for generating the copy "write to the file" */
if(pid == 0){
int out = 0;
/* test if file exists, if not create the file specified by user */
if((out_file = fopen(output_line, "r")) == NULL){
creat(output_line, "w");
fprintf(stderr, "File created\n");
}
/* write to file from buffer */
while(1){
/* wait(full) */
semop(semid, &Wait_Full, 1);
terminated_val = semctl(semid, SEM_TERMINATED, GETVAL);
if(terminated_val == 1){
write(out_file, buffer[out], (unsigned int) read_size);
fprintf(stderr, "File copy complete\n");
fclose(out_file);
semctl(semid, 4, IPC_RMID); /* remove the semaphores */
shmdt(shm_addr); /* detach shared memory for removal */
shmctl(shmid, IPC_RMID, NULL); /* remove shared memory */
return(0);
}
/* write the copy file from the buffer */
write(out_file, buffer[out], (unsigned int) read_size);
/* update the buffer */
out = (out+1)%(ITEM_SIZE*10);
/* signal(empty) */
semop(semid, &Signal_Empty, 1);
}
}
/* child process responsible for reading the file and passing it to the buffer */
else if (pid > 0){
int in = 0;
/* file entered by the user was not found */
if((in_file = fopen(input_line, "r")) == NULL){
fprintf(stderr, "File could not be opened\n");
perror("fopen");
}
/* file specified by user was found */
else
fprintf(stderr, "File Found\n");
while(1){
/* wait(empty) */
semop(semid, &Wait_Empty, 1);
/* read ITEM_SIZE into the buffer */
read_size = read(in_file, buffer[in], ITEM_SIZE);
fprintf(stderr, "%d\n", read_size);
/*update the buffer */
in = (in+1)%(ITEM_SIZE*10);
/* read_size must not be negative or error */
if(read_size < 0){
fprintf(stderr, "something bad happend\n");
exit(8);
}
/* end of file */
else if(read_size > 0 && read_size < ITEM_SIZE){
/* last of the file set last-transfer-size semaphore to size of file left */
semctl(semid, SEM_LAST_TRANS_SIZE, SETVAL, read_size);
fclose(in_file);
/* set the terminated semaphore to 1 */
semctl(semid, SEM_TERMINATED, SETVAL, 1);
semop(semid, &Signal_Full, 1);
}
/* signal(full) */
semop(semid, &Signal_Full, 1);
}
}
/* Oops fork did not happen */
else perror("fork\n");
}
|
| Dr Spud is offline | |
| | #4 |
| Registered User Join Date: Nov 2005 Location: Alpine, TX
Posts: 31
| So ive made some progress on my program and some significant changes that I think are for the best but I still have a problem. In this example I dont want to just set the buffer to a size that can handle the entire copy at once. I want to break the copying up so that read will deposit an item in buffer[in] and write will take that deposit at buffer[out] and write it to the copy. But when I do this I get an error of "Bad Adress". Would greatly appreciate some help with this. And as a trial run, I did abandon the idea of not having a large buffer to check if my file copy implementation worked. What I got was a binary file for the copy cant figure out why this happened. Any help on this matter also would help me greatly. thx for the help heres the codes Code: #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define ITEM_SIZE 4096
/* define semaphores within the set */
#define SEM_FULL 0
#define SEM_EMPTY 1
#define SEM_LAST_TRANS_SIZE 2
#define SEM_TERMINATED 3
char items[ITEM_SIZE];
char buffer[ITEM_SIZE * 10]; /* array of 10 items */
int in_file; /* input = file to read; output = file to write */
int out_file;
int read_size;
union semun
{
int val;
struct semid_ds *buf;
ushort *array;
} seminfo;
struct sembuf Wait_Empty={SEM_EMPTY, -1, 0};
struct sembuf Signal_Empty={SEM_EMPTY, 1, 0};
struct sembuf Wait_Full={SEM_FULL, -1, 0};
struct sembuf Signal_Full={SEM_FULL, 1, 0};
int main(int argc, char *argv[]){
int pid;
int terminated_val;
int read_size; /* number of bytes on last read */
/* gather shared memory space */
int shmid;
char * shm_addr;
shmid = shmget(IPC_PRIVATE, ITEM_SIZE * 10, IPC_CREAT); /* creat sh memory */
shm_addr = shmat(shmid, NULL, 0); /* attach sh memory */
/* get the 4 semaphores to be used */
int semid;
int stat;
semid = semget(IPC_PRIVATE, 4, 0600 | IPC_CREAT);
if (semid < 0)
perror("semget");
/* Initialize values for the 4 semaphores */
semctl(semid, SEM_FULL, SETVAL, 0);
stat = semctl(semid, SEM_EMPTY, SETVAL, 10);
if (stat < 0) perror("semctl sem_empty setval");
semctl(semid, SEM_LAST_TRANS_SIZE, SETVAL, 0);
semctl(semid, SEM_TERMINATED, SETVAL, 0);
/* gather the input file for the child to read from the user */
if (argc != 3) {
fprintf(stderr, "Error:Wrong number of arguments\n");
fprintf(stderr, "Usage is: copy <from> <to>\n");
exit(8);
}
in_file = open(argv[1], O_RDONLY);
if (in_file < 0) {
fprintf(stderr, "Error:Unable to open %s\n", argv[1]);
exit(8);
}
out_file = open(argv[2], O_WRONLY|O_TRUNC|O_CREAT, 0666);
if (out_file < 0) {
fprintf(stderr, "Error:Unable to open %s\n", argv[2]);
exit(8);
}
/* fork and cross fingers */
pid = fork();
/* parent process responsible for generating the copy "write to the file" */
if(pid == 0){
int out = 0;
/* write to file from buffer */
while(1){
/* wait(full) */
semop(semid, &Wait_Full, 1);
int last_trans_size;
last_trans_size = semctl(semid, SEM_LAST_TRANS_SIZE, GETVAL);
terminated_val = semctl(semid, SEM_TERMINATED, GETVAL);
if(terminated_val == 1){
write(out_file, buffer[out], last_trans_size);
fprintf(stderr, "File copy complete\n");
semctl(semid, 4, IPC_RMID); /* remove the semaphores */
shmdt(shm_addr); /* detach shared memory for removal */
shmctl(shmid, IPC_RMID, NULL); /* remove shared memory */
close(out_file);
close(in_file);
return(0);
}
/* write the copy file from the buffer */
write(out_file, buffer[out], ITEM_SIZE);
/* update the buffer */
out = (out+1)%(ITEM_SIZE*10);
/* signal(empty) */
semop(semid, &Signal_Empty, 1);
}
}
/* child process responsible for reading the file and passing it to the buffer */
else if (pid > 0){
int in = 0;
while(1){
/* wait(empty) */
semop(semid, &Wait_Empty, 1);
/* read ITEM_SIZE into the buffer */
read_size = read(in_file, buffer[in], ITEM_SIZE);
/* read_size must not be negative or error */
if (read_size < 0) {
fprintf(stderr, "Error:Read error\n");
perror("read");
exit(8);
}
in = (in+1)%(ITEM_SIZE*10);
/* end of file */
if(read_size > 0 && read_size < ITEM_SIZE){
/* last of the file set last-transfer-size semaphore to size of file left */
semctl(semid, SEM_LAST_TRANS_SIZE, SETVAL, read_size);
/* set the terminated semaphore to 1 */
semctl(semid, SEM_TERMINATED, SETVAL, 1);
! semop(semid, &Signal_Full, 1);
}
/* signal(full) */
semop(semid, &Signal_Full, 1);
}
}
/* Oops fork did not happen */
else perror("fork\n");
}
|
| Dr Spud is offline | |
| | #5 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| If you use gdb, do you get a stack-trace that can be used to deduce where the problem is? You can either do that by just running your code inside gdb, or use the core file that is generated when it crashes. I don't see anything OBVIOUS, but it's quite possible that there's problems someplace in the code. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #6 |
| Registered User Join Date: Nov 2005 Location: Alpine, TX
Posts: 31
| sure.... first off I am getting compiler warnings here they are if they will help you Code: sem.c: In function ‘main’: sem.c:108: warning: passing argument 2 of ‘write’ makes pointer from integer without a cast sem.c:118: warning: passing argument 2 of ‘write’ makes pointer from integer without a cast sem.c:134: warning: passing argument 2 of ‘read’ makes pointer from integer without a cast Code: (gdb) run read.txt foo.txt Starting program: /home/drspud/Desktop/sem read.txt foo.txt Error:Read error read: Bad address Program exited with code 010. |
| Dr Spud is offline | |
| | #7 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,661
| char items[ITEM_SIZE]; char buffer[ITEM_SIZE * 10]; /* array of 10 items */ No it isn't. It might be as big as an array of 10 items, but it sure isn't an array of 10 items. As a result, all your attempts to use buffer fail. char buffer[10][ITEM_SIZE]; might be of some use. And replacing the likes of in = (in+1)%(ITEM_SIZE*10); with in = (in+1)%10; |
| Salem is offline | |
| | #8 |
| Registered User Join Date: Nov 2005 Location: Alpine, TX
Posts: 31
| Awesome Salem thx for your post and help. Your suggestion worked like a charm now I just gotta figure out why my copied file is printed in binary instead of ASCII. Any good tutorials on this anyone could suggest? |
| Dr Spud is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Semaphores, need advice on implementation. | Swerve | C++ Programming | 2 | 01-13-2009 01:54 AM |
| Semaphores Problems | mhelal | Linux Programming | 2 | 05-06-2007 10:36 PM |
| Semaphores | Jules | C Programming | 4 | 01-18-2004 01:58 PM |
| semaphores | theLukerBoy | C Programming | 0 | 11-05-2002 01:46 AM |
| Semaphores | edk | C++ Programming | 1 | 11-25-2001 03:55 PM |