ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Could you please help me in finding out the reason behind segmentation fault. This program is working fine as long as the command line input is as follows:
I have tried my level best to resolve this and to find out the reason behind failing. But could not able to find the solution. While using dbx I came to know the point where it's failing but unfortunately I don't know how to resolve it.
I have mentioned the dbx output below to have a look at it and it may save your time to help me in solving this problem.
midibm14:subh:/home/users/subh/demo #dbx test
Type 'help' for help.
reading symbolic information ...
(dbx) stop in main
[1] stop in main
(dbx) r -r 300 -w 3 -s 100
[1] stopped in main at line 14 ($t1)
14 parse_args(argc, argv);
(dbx) c test: Shared Memory Test Program
Number of writers thread = 3
Number of readers thread = 300
Shared Memory Size in Bytes = 100
execution completed(dbx) q
midibm14:subh:/home/users/subh/demo #dbx test
Type 'help' for help.
reading symbolic information ...
(dbx) stop in main
[1] stop in main
(dbx) r -r 1 -w 4 -s 100
[1] stopped in main at line 14 ($t1)
14 parse_args(argc, argv);
(dbx) cont test: Shared Memory Test Program
Number of writers thread = 4
Number of readers thread = 1
Shared Memory Size in Bytes = 100
Shmat Failed Here *** : Shared Memory Attach Error : Too many open files
execution completed(dbx)
It's failing when I tried to increase the "-w option" in the 2nd execution.
Let me summarise the problem once again. I can run this program with the writer thread ("-w option") less than or equal to 3. But I can't run this program with the writer thread ("-w option") 4 or more.
May I request you to look into the problem and please provide me the solution.
#define USAGE "\nUsage: %s [-r num_readers] [-w num_writers] [-s shmem_size]\n
\n" \
"\t-r num_readers number of reader thread to create\n" \
"\t-w num_writers number of writer thread to create\n" \
"\t-s buffer_size size of shmem segments in bytes\n" \
"\t must be less than 256MB\n\n"
int thread_hold[MAX_WRITER_NUMBER];
pthread_mutex_t cond_mutex[MAX_WRITER_NUMBER];
pthread_mutex_t mutex_r[MAX_WRITER_NUMBER];
pthread_cond_t cond_var[MAX_WRITER_NUMBER];
int *read_count[MAX_WRITER_NUMBER];
char *shmptr[MAX_READER_NUMBER];
unsigned long *checksum[MAX_WRITER_NUMBER];
unsigned long cksum[MAX_WRITER_NUMBER];
int shmem_size = DEFAULT_SHMEM_SIZE;
pid_t parent_pid;
int num_readers = DEFAULT_NUM_READERS;
int buffer_size = DEFAULT_SHMEM_SIZE;
int num_writers = DEFAULT_NUM_WRITERS;
int shmid[MAX_THREAD_NUMBER + MAX_WRITER_NUMBER];
But I am not able to run the program as follows(It gives me the segmentation fault) and the reason is not known to me. ./main -r 1 -w 4 -s 100
I don't know why it fails, if I give "-w option" (4 or more). It works if "-w option" is less than or equal to 3.
It'll be of great help if you can look at the whole program and let me know where I am doing wrong. If possible do also provide me the solution as I have no clue to solve it.
Code:
/****************************************************/
/********************** header.h ********************/
/****************************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/signal.h>
/********************* User Defined Data ***************/
#define MAX_THREAD_NUMBER 5000
#define MAX_WRITER_NUMBER 100
#define MAX_READER_NUMBER 400
#define DEFAULT_NUM_READERS 2
#define DEFAULT_NUM_WRITERS 2
#define SHMEM_MODE (SHM_R | SHM_W)
#define DEFAULT_SHMEM_SIZE 20000
#define MB (1024*1024)
#define MAX_SHMEM_NUMBER 11
#define USAGE "\nUsage: %s [-r num_readers] [-w num_writers] [-s shmem_size]\n
\n" \
"\t-r num_readers number of reader thread to create\n" \
"\t-w num_writers number of writer thread to create\n" \
"\t-s buffer_size size of shmem segments in bytes\n" \
"\t must be less than 256MB\n\n"
/************ Global Functions ****************/
int parse_args(int , char **);
int *reader(void *);
int *writer(void *);
int error(const char *, int);
int release();
/*int sys_error(const char *, int);*/
/************ Global Variables ****************/
pthread_t *writer_th;
pthread_t *reader_th;
int thread_hold[MAX_WRITER_NUMBER];
pthread_mutex_t cond_mutex[MAX_WRITER_NUMBER];
pthread_mutex_t mutex_r[MAX_WRITER_NUMBER];
pthread_cond_t cond_var[MAX_WRITER_NUMBER];
int *read_count[MAX_WRITER_NUMBER];
char *shmptr[MAX_WRITER_NUMBER];
unsigned long *checksum[MAX_WRITER_NUMBER];
unsigned long cksum[MAX_WRITER_NUMBER];
int shmem_size = DEFAULT_SHMEM_SIZE;
pid_t parent_pid;
int num_readers = DEFAULT_NUM_READERS;
int buffer_size = DEFAULT_SHMEM_SIZE;
int num_writers = DEFAULT_NUM_WRITERS;
int shmid[MAX_THREAD_NUMBER + MAX_WRITER_NUMBER];
/****************************************************/
/********************** main.c **********************/
/****************************************************/
#include "header.h"
int main(int argc, char **argv)
{
pthread_attr_t newattr;
int i, j, k;
size_t Size;
unsigned long *ulptr;
parse_args(argc, argv);
printf("%s: Shared Memory Test Program\n\n", *argv);
printf("\tNumber of writers thread = %d\n", num_writers);
printf("\tNumber of readers thread = %d\n", num_readers);
printf("\tShared Memory Size in Bytes = %d\n", buffer_size);
printf("\n");
for(i = 0; i < num_writers; i++) {
j = i * 3;
Size = sizeof(int);
if((shmid[j] = shmget(IPC_PRIVATE, Size, SHMEM_MODE)) < 0)
perror("Shmget Error");
if((long)(read_count[i] = (int *) shmat(shmid[j], 0, 0)) == -1)
perror("Shmat Error");
*(read_count[i]) = 0;
j++;
Size = sizeof(unsigned long) * num_readers;
if((shmid[j] = shmget(IPC_PRIVATE, Size, SHMEM_MODE)) < 0)
perror("Checksum Shmget Failed");
if((long)(checksum[i] = (unsigned long *) \
shmat(shmid[j], 0, 0)) == -1)
perror("Shmat Failed : Shared Memory Attach Error ");
ulptr = checksum[i];
for(k = 0; k < num_readers; k++)
{
*ulptr = 0;
ulptr++;
}
Size = buffer_size;
j++;
if((shmid[j] = shmget(IPC_PRIVATE, Size, SHMEM_MODE)) < 0)
perror("Shmptr Shmget Failed");
if((long)(shmptr[i] = shmat(shmid[j], 0, 0)) == -1)
perror("Shmat Failed Here *** : Shared Memory Attach Error ");
}
writer_th = (pthread_t *) malloc((size_t) (num_writers \
* sizeof(pthread_t)));
reader_th = (pthread_t *) malloc((size_t) (num_writers \
* num_readers * sizeof(pthread_t)));
for(i = 0; i < num_writers; i++) {
if(pthread_mutex_init(&mutex_r[i] , (pthread_mutexattr_t *)NULL) != 0)
perror("Can't Initialise Mutex");
if(pthread_mutex_init (&cond_mutex[i], (pthread_mutexattr_t *)NULL)!=0)
perror("Can't Initialize Cond_Mutex");
if(pthread_cond_init (&cond_var[i], (pthread_condattr_t *)NULL)!=0)
perror("Cond_Var Failed");
thread_hold[i] = 1;
}
if(pthread_attr_init(&newattr))
perror("Attr_Init Failed");
if(pthread_attr_setdetachstate(&newattr, PTHREAD_CREATE_UNDETACHED))
perror("Attr_Setdetachstate Failed");
for(i = 0; i < num_writers; i++)
{
if(pthread_create(&writer_th[i], &newattr, writer, \
(void *) (long)i))
perror("Writer Failed");
k = i * num_readers;
for(j = k; j < (k + num_readers) ; j++)
{
if(pthread_create(&reader_th[j], &newattr, reader,\
(void *) (long)j))
perror("Reader Failed");
}
}
for(i = 0; i < num_writers; i++)
{
if(pthread_join(writer_th[i], NULL)) {
printf("writer_th: pthread_join return: %d\n",i);
perror("Pthread_join Bad Status");
}
k = i * num_readers;
for(j = k; j < (k + num_readers) ; j++)
{
if(pthread_join(reader_th[j], NULL)) {
perror("Pthread_join Bad Status");
}
}
}
for(i = 0; i < num_writers; i++)
{
ulptr = checksum[i];
for(j = 0; j < num_readers; j++) {
if(cksum[i] != *ulptr )
error("checksums do not match", __LINE__);
}
}
printf("\n\tMain: Readers calculated segment successfully\n");
release();
printf("\nsuccessful!\n");
return(0);
}
/****************************************************/
/******************** reader.c **********************/
/****************************************************/
#include "header.h"
void *reader(void *parm)
{
int num_p = (int) (long)parm;
unsigned long cksum_r = 0;
int i, num_r, num_w;
char *ptr;
unsigned long *ulptr_r;
num_r = num_p % num_readers;
num_w = num_p - num_r;
num_w = num_w / num_readers;
ptr = shmptr[num_w];
ulptr_r = checksum[num_w];
if(pthread_mutex_lock (&cond_mutex[num_w]))
perror("Can't Take Cond Lock");
while(thread_hold[num_w])
{
if(pthread_cond_wait(&cond_var[num_w], &cond_mutex[num_w]))
perror("cond_wait failed");
}
if(pthread_mutex_unlock(&cond_mutex[num_w]))
perror("Release cond Lock Failed");
if(pthread_mutex_lock(&mutex_r[num_w]))
perror("Can't take read Lock");
(*(read_count [num_w]))++;
if(pthread_mutex_unlock(&mutex_r[num_w]))
perror("Can't Release Read Lock");
for(i = 0; i < buffer_size; i++)
cksum_r += *ptr++;
if(pthread_mutex_lock(&mutex_r[num_w]))
perror("Can't Take Read Lock");
(*(read_count[num_w]))--;
if(pthread_mutex_unlock(&mutex_r[num_w]))
perror("Can't Release 1 Read Lock");
*ulptr_r = cksum_r;
printf("\tReader (%d) of Writer (%d): checksum %04ld\n",\
num_r,num_w,cksum_r);
return NULL;
}
/****************************************************/
/******************** writer.c **********************/
/****************************************************/
#include "header.h"
void *writer(void *parm)
{
int num_w = (int) (long)parm;
unsigned long cksum_w = 0;
char data = 0;
char *ptr;
int count = 0;
data = num_w;
for(ptr = shmptr[num_w]; ptr < (shmptr[num_w]+buffer_size); ptr++) {
*ptr = data++;
cksum_w += *ptr;
}
/*perror("Writer: Writer failed here 0: ");*/
if(pthread_mutex_lock(&cond_mutex[num_w]))
perror("Mutex_lock Failed");
thread_hold[num_w] = 0;
if(pthread_cond_broadcast(&cond_var[num_w]))
perror("cond_signal Failed");
if(pthread_mutex_unlock(&cond_mutex[num_w]))
perror("Mutex_unlock Failed");
cksum[num_w] = cksum_w;
printf("\n\tWriter (%d): shared memory checksum %04ld\n", \
num_w, cksum_w);
return NULL;
}
/****************************************************/
/******************** parseargs.c *******************/
/****************************************************/
#include "header.h"
int parse_args(int argc, char **argv)
{
int i;
int errflag = 0;
char *program_name = *argv;
extern char *optarg;
while((i = getopt(argc, argv, "r:s:w:?")) != EOF) {
switch (i) {
case 'r':
num_readers = atoi(optarg);
break;
case 's':
buffer_size = atoi(optarg);
break;
case 'w':
num_writers = atoi(optarg);
break;
case '?':
errflag++;
break;
}
}
if(num_writers >= MAX_WRITER_NUMBER) {
errflag++;
fprintf(stderr, "ERROR: num_writers must be less\
than %d\n", MAX_WRITER_NUMBER);
}
if(num_readers >= MAX_READER_NUMBER) {
errflag++;
fprintf(stderr, "ERROR: num_readers must be less\
than %d\n", MAX_READER_NUMBER);
}
i = num_readers * num_writers;
if(i >= MAX_THREAD_NUMBER) {
errflag++;
fprintf(stderr, "ERROR: maximun threads number\
must be less than %d\n", MAX_THREAD_NUMBER);
}
if(errflag) {
fprintf(stderr, USAGE, program_name);
exit (2);
}
}
int release()
{
int i, j;
for(i = 0; i < num_writers; i++) {
if(pthread_mutex_destroy(&cond_mutex[i]) != 0)
perror("Can't destroy cond_mutex");
if(pthread_mutex_destroy(&mutex_r[i]) != 0)
perror("Can't destroy mutex_r");
}
for(i = 0; i < num_writers; i++) {
j = i * 3;
if(shmctl(shmid[j], IPC_RMID, 0) < 0)
perror("Read_count shmctl Failed");
j++;
if(shmctl(shmid[j], IPC_RMID, 0) < 0)
perror("checksum shmctl failed");
j++;
if(shmctl(shmid[j], IPC_RMID, 0) < 0)
perror("shmptr shmctl failed");
}
}
int sys_error(const char *msg, int line)
{
char syserr_msg [256];
sprintf(syserr_msg, "%s: %s\n", msg, strerror (errno));
error(syserr_msg, line);
}
int error(const char *msg, int line)
{
fprintf(stderr, "ERROR [line: %d] %s\n", line, msg);
if(line>= 260)
release();
exit(-1);
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.