I am getting core dump by this little programm.
#include <dirent.h>
int main(void) {
printf("process n%s",(long)getpid());
exit(0);
}
can you explain me why?
You need to know where your functions come from, what they're returning and how to print the return value.
#include <unistd.h>
#include <stdio.h>
int main(void) {
printf("process n%ld", (long)getpid());
}
Related
I can not figure out where I'm wrong, after running the code arrived in the for where it runs the pthread_join() , many pthread_join() return with value 3 instead of 0. Furthermore, printing the value of i is not always consistent and this causes segmentation fault and printing several times of the same position.
Code modified as required in the comments
all the includes are for other parts of the program. Testing only this piece of code creates segmentation fault at error 3 on pthread_join()
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <errno.h>
#include <config.h>
#include <sys/select.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
void *threadF(){
printf("hello\n");
pthread_exit((void*)0);
}
int main(int argc, char *argv[]) {
FILE *fileconf=fopen(argv[2],"r");
if(fileconf==NULL){
fprintf(stderr, "Fopen\n",argv[2]);
return -1;
}
set_conf(fileconf); //parse fileconf and set THREADSINPOOL correctly
pthread_t array[THREADSINPOOL];
int i,err,s=0;
for(i=0;i<THREADSINPOOL;i++){
if((err=pthread_create(&array[i],NULL,&threadF,NULL))!=0){
fprintf(stderr,"thread\n");
exit(errno);
}
}
int tmp;
for(i=0;i<THREADSINPOOL;i++){
tmp=pthread_join(array[i],(void *)&s);
printf("thread: %lu terminated\n tmp: %d\n",array[i],tmp);
}
return 0;
}
The problem is that you are passing the address of an int to a function that expects the address of a void *. On a 64-bit system, there's a good chance that an int is only 32-bits whereas a void * is 64-bits. So pthread_join ends up writing 64-bits into a location that is only big enough for 32-bits. The result is that you overwrite memory that shouldn't being changed, and all sorts of undefined behavior follows.
Here's a way to write the code so that the second argument to pthread_join is actually a pointer to a void *
for (i = 0; i < THREADSINPOOL; i++)
{
void *value;
if (pthread_join(array[i], &value) == 0)
printf("thread %d returned %" PRIiPTR "\n", i, (intptr_t)value);
else
printf("thread %d failed\n", i);
}
I'm trying to implement the producer/consumer problem in C. I know how to handle it with "fork", but in this case I shall implement two programs. One for producer and one for consumer.
For producer: a semaphore has to be initialized and in a loop (to 100), the semaphore shall increment its value and print it. This already works fine.
For consumer: the semaphore initialized in producer, shall be opened and in a loop (to 10) its value shall be decremented and printed.
When I run the process for consumer: a memory-access error is printed.
I have absolutely no idea, what I'm doing wrong. Thanks for any help!
consumer:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
int value;
sem_t *mySem = sem_open("sem", O_CREAT|O_EXCL , S_IRUSR|S_IWUSR , 0);
for(int i=0; i < 10; i++) {
sem_wait(mySem);
sem_getvalue(mySem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_close(mySem);
sem_unlink("sem");
return 0;
}
producer:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
sem_t sem;
int main() {
sem_init(&sem, 0, 0);
int value;
for(int i=0; i < 100; i++) {
sleep(1);
sem_post(&sem);
sem_getvalue(&sem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_destroy(&sem);
return 0;
}
Hmm, what do you expect sem_init(&sem, 0, 0); to do? What relationship does that sem have with the consumer?
For two unrelated processes to communicate over anyn IPC, they have to agree on a resource by name. That's true if they share a file. It's also true if they share a semaphore. That's what named semaphores are for.
I modified your programs to use one named semaphore. The producer creates it and owns it exclusively; the consumer errors out if it's not there.
Consumer:
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/types.h>
static const char name[] = "sem";
int main() {
int value;
sem_t *sem = sem_open(name, 0, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
for(int i=0; i < 10; i++) {
sem_wait(sem);
sem_getvalue(sem, &value);
printf("The value of the semaphore is %d\n", value);
}
if( -1 == sem_close(sem) ) {
err(EXIT_FAILURE, "sem_close");
}
if( -1 == sem_unlink(name) ) {
err(EXIT_FAILURE, "sem_unlink");
}
return 0;
}
Producer:
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static const char name[] = "sem";
int main() {
sem_unlink(name); // ignore error if not extant
int value;
sem_t *sem = sem_open(name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
for(int i=0; i < 100; i++) {
sleep(1);
sem_post(sem);
sem_getvalue(sem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_destroy(sem);
return 0;
}
I think you'll find they work better now. I recommend you follow my lead, though, and check every return code, and exit on error whenever anything goes wrong. For trial code like this, that's the quickest way to get it running correctly.
Thanks for correction. This works perfectly for my purpose.
With sem_init I supposed to initialize the semaphore with 0 as Start-Value.
Seems like the error was using this instead of a pointer and sem_open in the producer-process.
This was my first experience with named semaphores, so it was not easy to see my error.
Thank you very much
I have a program that prepares some configurations in one process and after that reads those configurations in the parent process. To sync them I'm using semaphores from semaphore.h library. But it seems that it's waiting forever in sem_wait even after I sem_post. It works after I do ctrl-z and fg though. Why is that? Can anyone tell me what's wrong with my code?
My OS is Lubuntu
Semaphore1.h
#ifndef _DNSS_H_
#define _DNSS_H_
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include <sys/types.h>
typedef struct configs
{
int i;
sem_t sem;
} CONFIGS;
void init_config(CONFIGS *_configs);
//initiates the threadpool
int init_thread_pool(CONFIGS *configs);
#endif
Semaphore_1.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <semaphore.h>
#include <pthread.h>
#include "semaphore1.h"
void init_config(CONFIGS *_configs)
{
sem_init(&(_configs->sem),1,0); //Creaates a semaphore that is opened when the configs are read to shared memory
_configs->i=2;
fprintf(stderr, "Result of sem_post:%d\n", sem_post(&(_configs->sem)));
}
Semaphore_2.c
#include"semaphore1.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int init_thread_pool( CONFIGS *configs)
{
int aux;
fprintf(stderr, "Value of sem_wait():%d\n", sem_wait(&(configs->sem)));
printf("Threadpool initiated with %d threads!", configs->i);
return 1;
}
Semaphore_main.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include "semaphore1.h"
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char *argv[])
{
pid_t config_pid; //will hold the configuration process id
int _shmid_configs;
CONFIGS *_configs;
_shmid_configs =shmget( IPC_PRIVATE,
sizeof(CONFIGS), IPC_CREAT|0666); //initializes the shared memory
if( _shmid_configs == -1)
{
perror("Error creating shared memory");
}
_configs=shmat(_shmid_configs, NULL,0); //maps the shared memory created to the processp and the config structure
if( _configs == ( CONFIGS*)-1)
{
perror("Error at shmat");
}
//initialization of the processes
config_pid = fork();
if( config_pid < 0)
{
perror("Failed creating configuration manager process");
}
else if( config_pid == 0)
{
init_config(_configs);
printf("Im config!\n");
return 0;
}
//CODE FOR THE gestor de pedidos
printf("right before the threadpool! Configs has a lmit of %d theads\n", _configs->i);
init_thread_pool(_configs);
printf("im parent and im out\n");
sem_destroy(&_configs->sem);
return 0;
}
Compiled with
gcc -g -pthread Semaphore_2.c Semaphore_main.c Semaphore_1.c -o deb
Output:
./deb
right before the threadpool! Configs has a lmit of 0 theads
Result of sem_post:0
Im config!
^Z
[1]+ Stopped ./deb
fg
./deb
Value of sem_wait():0
Threadpool initiated with 2 threads!im parent and im out
sem_init() should be called before fork().
In your current code it is possible for init_thread_pool(_configs); in the parent thread to be called before init_config(), that is you will wait on uninitialized semaphore. It is undefined behaviour.
I'm just new to the piping I/O functions within Linux.
2 c-files were made, the first sends data:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int i = 0;
for(;;)
{
printf("\nSent number: %d",i);
i++;
sleep(1);
fflush(stdout);
}
return 0;
}
The second files receives the printed number and displays it:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int x;
for(;;)
{
scanf("%d",&x);
printf("Received number: %d\n",x);
sleep(1);
fflush(stdout);
}
return 0;
}
Finally I try to redirect the data from the first file to the second with:
./send_test.out | ./rcv_test.out
The Terminal prints repeatedly: "Received number: 0", what am I doing wrong?
Also, how can I have to terminal windows for both programs running simultaneously while directing the output from the sender to the receiver?
Thanks in advance
You are not "sending" the number in a format the the receiver can understand.
Try removing all text except the %d from the sender's formatting string.
Also, you should check the return value of scanf() before relying on it.
I am looking for a peace of code to check if the argument I pass to my program is a directory or not. So far I found this:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct stat buf;
stat(argv[1],&buf);
exit(0);
}
But it does not really help me.
Use:
if(S_ISDIR(buf.st_mode))
printf(" Its a directoy\n");
else
printf("Its a file\n");
after stat(argv[1],&buf); call