Program stuck in while loop - c

I was trying to use semaphores in a while loop and my program is running in an infinite loop. Basically I fork off children and use execv to start new user processes. The processes use semaphore in shared memory to communicate.
struct shared
{
int count;
sem_t sem;
} *shmem;
void forking()
{
key_t shmkey = ftok("makefile",777);
if (shmkey == -1) {
perror("Ftok failed");
exit(-1);
}
// Get our shm id
shmid = shmget(shmkey, sizeof(shared), 0666 | IPC_CREAT);
if (shmid == -1) {
perror("Failed to allocate shared memory region");
exit(-1);
}
// Attach to our shared memory
shmem = (shared*)shmat(shmid, (void *)0, 0);
if (shmem == (void *)-1) {
perror("Failed to attach to shared memory region");
exit(-1);
}
sem_init(&(shmem->sem),1,1);
pid_t PID;
int i;
for(i=0;i<4;i++)
{
PID=fork();
if(PID==0)
{
static char *args[]={"./child",NULL};
int status;
if(( status= (execv(args[0], args)))==-1)
perror("failed to execv");
exit(EXIT_FAILURE);
}
if(PID>0)
{
while(1)
{
sem_wait(&(shmem->sem));
{
shmem->count=shmem->count+1;
}
sem_post(&(shmem->sem));
}
}
if(PID<0)
perror("error in fork");
}
}
main()
{
forking();
}
in child.c
struct shared
{
int count;
sem_t sem;
} shmem;
void main()
{
bool alive=true;
do
{
sem_wait(&(shmem->sem));
if(shmem->count==5)
{
shmem->count=0;
alive=false;
}
sem_post(&(shmem->sem));
}while(alive);
}
child.c loops endlessly without allowing parent to increment i till 5. This happens even if I comment out while loop in first file and just let it increment without loops.In the end nothing exits.

You are using fork wrong, and definitely not using shared memory.
Here's some few point
By calling fork, you are making a copy of parent running in different memory space. http://man7.org/linux/man-pages/man2/fork.2.html
By using execve, you essentially delete the old memory and replace it with a new one which are not linked in anyway to your parent process. http://man7.org/linux/man-pages/man2/execve.2.html
To make your code work, you should be using pthread_* instead as it will live in the same memory space and make your global variable volatile as gcc will try to optimize and will have weird behaviors if it does so.
Ok it seems I've missed quite a few points while being not totally wrong on my assumption.
So your child.c is missing quite a few bit of code
It does not contains all the initialization you've made in your parent which is necessary because if you use execve you essentially lost every memory mapping you've mapped previously in your parent process.
Your parents loops infinitely so shmem->count will never really equals to 5, you will have to break at some moment or change your condition in your child code.
Here's what your child should look like.
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct
{
int count;
sem_t sem;
} shared;
shared *shmem;
int shmid;
key_t shmkey;
int main()
{
int alive=1;
shmkey = ftok("makefile",777);
if (shmkey == -1) {
perror("Ftok failed");
exit(-1);
}
// Get our shm id
shmid = shmget(shmkey, sizeof *shmem, 0);
if (shmid == -1) {
perror("Failed to allocate shared memory region");
exit(-1);
}
// Attach to our shared memory
shmem = (shared*)shmat(shmid, (void *)0, 0);
if (shmem == (shared *)-1) {
perror("Failed to attach to shared memory region");
exit(-1);
}
do
{
sem_wait(&(shmem->sem));
printf("%d\n", shmem->count);
if(shmem->count > 5)
{
shmem->count=0;
alive=0;
}
sem_post(&(shmem->sem));
}while(alive);
printf("I have finished %u\n", getpid());
exit(0);
}

Related

Permission denied issue in mmap function in shared memory in C

In the child process the mapping is giving me issue. the parent is creating a shared memory and child is using it for writing a message to parent but when the mmap executes, it gives an error of permission denied. kindly help me to get rid of this issue. everything else is running file. when I try to create shared memory in child process the issue is resolved but the requirement is creating shared memory in parent process, that is why it is taking time to solve it.
/**
* Simple program demonstrating shared memory in POSIX systems.
*
* This is the consumer process
*
* Figure 3.18
*
* To compile, enter
* gcc shm-posix-consumer.c -lrt
*
* #author Gagne, Galvin, Silberschatz
* Operating System Concepts - Tenth Edition
* Copyright John Wiley & Sons - 2018
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mman.h>
int main()
{
const int SIZE = 4096;
const char *name = "OS";
//shm_unlink(name);
int shm_fd;
void *ptr;
pid_t pid;
pid=fork();
if(pid==-1) {
printf("Error in creating a child process\n");
return -1;
}
else if(pid==0) {
sleep(2);
printf("child process is executing\n");
/* open the shared memory segment */
shm_fd = shm_open(name, O_RDWR, S_IRWXU);
if (shm_fd == -1) {
printf("opening of shared memory failed\n");
exit(-1);
}
if(ftruncate(shm_fd,SIZE)==-1){
printf("Error in configuring the size of shared memory");
exit(1);
}
/* now map the shared memory segment in the address space of the process */
ptr = mmap(0,SIZE,PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
perror("Map failed in child process\n");
printf("error:%s %d",strerror(errno),errno);
return -1;
}
char *message0;
strcpy(message0,"Greeting to parent");
printf("Message to parent from child:%s\n",message0);
sprintf(ptr,"%s",message0);
ptr += strlen(message0);
if(munmap(ptr,SIZE)==-1){
printf("munmap error:\n");
exit(1);
}
close(shm_fd);
}
else {
printf("parent process is executing\n");
/* create the shared memory segment */
shm_fd = shm_open(name, O_CREAT | O_RDWR, S_IRWXU);
/* configure the size of the shared memory segment */
if(ftruncate(shm_fd,SIZE)==-1){
printf("Error in configuring the size of shared memory");
exit(1);
}
printf("parent process wait after creating shared memory\n");
wait(NULL);
printf("back to parent process after child termination\n");
/* now map the shared memory segment in the address space of the process */
ptr = mmap(0,SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
printf("Map failed in parent\n");
return -1;
}
printf("%s\n",(char *)ptr);
if (shm_unlink(name) == -1) {
printf("Error removing %s\n",name);
exit(-1);
}
}
return 0;
}
At least three problems:
char *message0;
strcpy(message0,"Greeting to parent");
You are using message0 uninitialized, switch to something like
char message0[64];
strcpy(message0,"Greeting to parent");
or simply:
char *message0 = "Greeting to parent";
Here:
void *ptr;
...
ptr += strlen(message0);
You can't use pointer arithmetic with void *, switch to char *ptr;
And here:
ptr += strlen(message0);
if(munmap(ptr,SIZE)==-1){
you need to rewind ptr to the original position returned by mmap before calling munmap, it seems that you can remove this line:
ptr += strlen(message0);
Now it works for me adding #define _XOPEN_SOURCE 500 at the very beginning (for ftruncate).

synchronisation problem in multiple threads of multiple processes

I have a code. There are 2 processes. Parent is writer on file a.txt. Child is reader on a.txt.Parent has 2 threads and child has 2 threads. Parent's 1st thread opens a file parent1.txt . reads 128 chars. writes to a.txt.Parent's 2nd thread opens file parent2.txt.reads 128 chars. writes to a.txt. Child's 1st thread reads 128 chars from a.txt and writes to child1.txt. child's 2nd thread reads 128 chars from a.txt and child2.txt. Any parent thread , after writing, should generate event and invoke the child's reader threads.I have implemented a solution using mutex and condition variable.Parent's writer threads generate pthread_cond_signal after writing to a.txt. 1>But child's reader threads are not running after that. both parent threads are running in loop.2>Parent reads frm parent1.txt. the fread is successfull. But when it writes to a.txt, it is not successfull. the a.txt file is always empty.I think mutex can not be use between multiple processes. That may be 1 problem
My code is as follows
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
FILE*fd,*fdRead1,*fdRead2,*fdWrite1,*fdWrite2;
pthread_mutex_t *mut1;
pthread_mutexattr_t attrmutex;
pthread_cond_t *cond_var;
pthread_condattr_t attrcond;
#define OKTOWRITE "/condwrite"
#define MESSAGE "/msg"
#define MUTEX "/mutex_lock"
void* R1(void *)
{
char buf[128];
int size;
fdWrite1 = fopen("child1.txt","w+");
cout<<"R1Thread"<<endl;
for(int i=0;i<10;i++)
{
cout<<"R1Thread-1"<<endl;
pthread_mutex_lock(mut1);
pthread_cond_wait(cond_var,mut1);
cout<<"R1Thread-2"<<endl;
size = fread(buf,128,1,fd);
fwrite(buf,size,1,fdWrite1);
pthread_mutex_unlock(mut1);
}
fclose(fdWrite1);
}
void* R2(void *)
{
char buf[128];
int size;
fdWrite2 = fopen("child2.txt","w+");
cout<<"R2Thread"<<endl;
for(int i=0;i<10;i++)
{
cout<<"R2Thread-1"<<endl;
pthread_mutex_lock(mut1);
pthread_cond_wait(cond_var,mut1);
cout<<"R2Thread-2"<<endl;
size = fread(buf,128,1,fd);
fwrite(buf,size,1,fdWrite2);
pthread_mutex_unlock(mut1);
}
fclose(fdWrite2);
}
void* W1(void *)
{
char buf[128];
int size;
fdRead1 = fopen("parent1.txt","r");
for(int i=0;i<10;i++)
{
pthread_mutex_lock(mut1);
size = fread(buf,128,1,fdRead1);
fwrite(buf,size,1,fd);
pthread_cond_signal(cond_var);
cout<<"W2Thread-1"<<endl;
pthread_mutex_unlock(mut1);
sleep(10);
}
fclose(fdRead1);
}
void* W2(void *)
{
char buf[128];
int size;
fdRead2 = fopen("parent2.txt","r");
for(int i=0;i<10;i++)
{
pthread_mutex_lock(mut1);
size = fread(buf,128,1,fdRead2);
fwrite(buf,size,1,fd);
pthread_cond_signal(cond_var);
cout<<"W2Thread-1"<<endl;
pthread_mutex_unlock(mut1);
sleep(1000);
}
fclose(fdRead2);
}
int main()
{
int des_cond, des_msg, des_mutex;
int mode = S_IRWXU | S_IRWXG;
des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);
if (des_mutex < 0) {
perror("failure on shm_open on des_mutex");
exit(1);
}
if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1) {
perror("Error on ftruncate to sizeof pthread_cond_t\n");
exit(-1);
}
mut1 = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);
if (mut1 == MAP_FAILED ) {
perror("Error on mmap on mutex\n");
exit(1);
}
des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);
if (des_cond < 0) {
perror("failure on shm_open on des_cond");
exit(1);
}
if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1) {
perror("Error on ftruncate to sizeof pthread_cond_t\n");
exit(-1);
}
cond_var = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);
if (cond_var == MAP_FAILED ) {
perror("Error on mmap on condition\n");
exit(1);
}
/* Initialise attribute to mutex. */
pthread_mutexattr_init(&attrmutex);
pthread_mutexattr_setpshared(&attrmutex, PTHREAD_PROCESS_SHARED);
/* Allocate memory to pmutex here. */
/* Initialise mutex. */
pthread_mutex_init(mut1, &attrmutex);
/* Initialise attribute to condition. */
pthread_condattr_init(&attrcond);
pthread_condattr_setpshared(&attrcond, PTHREAD_PROCESS_SHARED);
/* Allocate memory to pcond here. */
/* Initialise condition. */
pthread_cond_init(cond_var, &attrcond);
pthread_t thR1,thR2,thW1,thW2;
fd = fopen("a.txt","w+");
int res = fork();
if(res<0) perror("error forking\n");
if(res==0)//child
{
cout<<"child created"<<endl;
pthread_create(&thR1,0,R1,0);
//pthread_create(&thR2,0,R2,0);
pthread_join(thR1,0);
//pthread_join(thR2,0);
fclose(fd);
}
else//parent
{
//fdRead = fopen("parent.txt","r");
pthread_create(&thW1,0,W1,0);
//pthread_create(&thW2,0,W2,0);
pthread_join(thW1,0);
//pthread_join(thW2,0);
fclose(fd);
wait(0);
}
}
The output is as follows-
child created
W2Thread-1
R1Thread
R1Thread-1
W2Thread-1
W2Thread-1
W2Thread-1
W2Thread-1
W2Thread-1
W2Thread-1
W2Thread-1
W2Thread-1
The condition_wait in child never comes out.
There are potential issues with using multiple processes, each with multiple threads, but they mostly revolve around program state at the time of the fork. Since your program forks before it creates any additional threads, you can be confident about its state at that time, and in particular, you can be confident that its one thread is not at that time executing in a critical section. This is fine.
However, you are missing two key details:
Although you set the mutex to be process-shared, the version of the code you initially presented failed to do the same for the condition variable.
Setting pthread_* synchronization objects to be process-shared is necessary, but not sufficient, for inter-process use. For that, you need the synchronization objects to reside in shared memory accessed by all participating processes. Only that way can all the process access the same objects.

Using semaphores between processes [duplicate]

Let's say I create a semaphore. If I fork a bunch of child processes, will they all still use that same semaphore?
Also, suppose I create a struct with semaphores inside and forked. Do all the child processes still use that same semaphore? If not, would storing that struct+semaphores in shared memory allow the child processes to use the same semaphores?
I'm really confused about how my forked child processes can use the same semaphores.
Let's say I create a semaphore. If I fork a bunch of child processes, will they all still use that same semaphore?
If you are using a SysV IPC semaphore (semctl), then yes. If you are using POSIX semaphores (sem_init), then yes, but only if you pass a true value for the pshared argument on creation and place it in shared memory.
Also, suppose I create a struct with semaphores inside and forked. Do all the child processes still use that same semaphore? If not, would storing that struct+semaphores in shared memory allow the child processes to use the same semaphores?
What do you mean be 'semaphores inside'? References to SysV IPC semaphores will be shared, because the semaphores don't belong to any process. If you're using POSIX semaphores, or constructing something out of pthreads mutexes and condvars, you will need to use shared memory, and the pshared attribute (pthreads has a pshared attribute for condvars and mutexes as well)
Note that anonymous mmaps created with the MAP_SHARED flag count as (anonymous) shared memory for these purposes, so it's not necessary to actually create a named shared memory segment. Ordinary heap memory will not be shared after a fork.
Let's say I create a semaphore. If I fork a bunch of child processes,
will they all still use that same semaphore?
It depends how you created the semaphore, to do that with an IPC semaphore see semaphore.c: Illustration of simple semaphore passing for an example.
Also, suppose I create a struct with semaphores inside and forked. Do
all the child processes still use that same semaphore? If not, would
storing that struct+semaphores in shared memory allow the child
processes to use the same semaphores?
For that to work your semaphore needs to be stored in an area shared between the parent and the child process like shared memory, and not just created on the stack or on the heap because it will be copied when the process forks.
I'm really confused about how my forked child processes can use the
same semaphores.
The semaphore can be shared across threads or processes. Cross-process sharing is implemented on the operating system level. Two or more different processes can share the same semaphore even if those processes were not created by forking a single parent process.
See this example for sharing an unnamed UNIX semaphore between a parent process and its child (to compile with gcc you'll need the -pthread flag):
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int main(void)
{
/* place semaphore in shared memory */
sem_t *sema = mmap(NULL, sizeof(*sema),
PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,
-1, 0);
if (sema == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
/* create/initialize semaphore */
if ( sem_init(sema, 1, 0) < 0) {
perror("sem_init");
exit(EXIT_FAILURE);
}
int nloop=10;
int pid = fork();
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) {
/* child process*/
for (int i = 0; i < nloop; i++) {
printf("child unlocks semaphore: %d\n", i);
if (sem_post(sema) < 0) {
perror("sem_post");
}
sleep(1);
}
if (munmap(sema, sizeof(sema)) < 0) {
perror("munmap");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
if (pid > 0) {
/* back to parent process */
for (int i = 0; i < nloop; i++) {
printf("parent starts waiting: %d\n", i);
if (sem_wait(sema) < 0) {
perror("sem_wait");
}
printf("parent finished waiting: %d\n", i);
}
if (sem_destroy(sema) < 0) {
perror("sem_destroy failed");
exit(EXIT_FAILURE);
}
if (munmap(sema, sizeof(sema)) < 0) {
perror("munmap failed");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
}
The output will be:
parent starts waiting: 0
child unlocks semaphore: 0
parent finished waiting: 0
parent starts waiting: 1
child unlocks semaphore: 1
parent finished waiting: 1
...
You may want to read Semaphores in Linux as well, but be aware that the example of UNIX semaphores across fork given doesn't work because the author forgot to use the MAP_ANONYMOUS flag in mmap.
Try this
child and parent would increment the shared variable alternatively
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
struct test {
sem_t mutex1;
sem_t mutex2;
int temp;
}test1;
int main(int argc, char **argv)
{
int fd, i,count=0,nloop=10,zero=0,*ptr;
struct test *testptr;
//open a file and map it into memory
sem_t mutex;
fd = open("log.txt",O_RDWR|O_CREAT,S_IRWXU);
write(fd,&zero,sizeof(int));
ptr = mmap(NULL, sizeof(struct test),PROT_READ |PROT_WRITE,MAP_SHARED,fd,0);
close(fd);
memcpy(ptr, &test1, sizeof(test1));
testptr = (struct test *)ptr;
// testptr = (struct test *)&test1;
/* create, initialize semaphore */
if( sem_init(&(testptr->mutex1),1,1) < 0)
{
perror("semaphore initilization");
exit(0);
}
/* create, initialize semaphore */
if( sem_init(&(testptr->mutex2),1,0) < 0)
{
perror("semaphore initilization");
exit(0);
}
if (fork() == 0) { /* child process*/
for (i = 0; i < nloop; i++) {
sem_wait(&(testptr->mutex2));
printf("child: %d\n", testptr->temp++);
sem_post(&(testptr->mutex1));
}
exit(0);
/* back to parent process */
for (i = 0; i < nloop; i++) {
sem_wait(&testptr->mutex1);
printf("parent: %d\n", testptr->temp++);
sem_post(&(testptr->mutex2));
}
exit(0);
}

Shared memory linux

I'm trying to work with shared memory at the first time. I created one child process and I write to the shared memory from Parent and change it from Child, before program ends I print shared memory from Parent and shared memory hasn't change, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <signal.h>
sem_t *semaphore;
int main(){
int i = 0, status;
pid_t pid=fork(), w;
int id;
if ((id = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) == -1){
perror("shmget");
exit(1);
}
int *sh;
if ((sh =(int *) shmat(id, NULL, 0)) == NULL){
perror("shmat");
exit(1);
}
*sh = 10;
if ((semaphore = sem_open("/semaphore", O_CREAT, 0666, 0)) == SEM_FAILED){
perror("semaphore");
exit(1);
}
if (pid==0) {
while(1){
sleep(1);
*sh = 50;
printf("child %d, %d\n", i, *sh);
i++;
if(i == 5){
sem_post(semaphore);
exit(0);
}
}
} else if (pid==-1) {
perror("process error\n");
} else {
printf("Parent, %d\n", *sh);
sem_wait(semaphore);
printf("child end => parent end\n");
printf("Parent, %d\n", *sh);
}
shmctl(id, IPC_RMID, NULL);
sem_close(semaphore);
sem_unlink("/semaphore");
return 0;
}
If I understand shared memory little bit than I can change it from everywhere if I have a pointer in my case is a "sh".
Output of program is:
Parent, 10
child 0, 50
child 1, 50
child 2, 50
child 3, 50
child 4, 50
child end => parent end
Parent, 10
Why is the number in shared memory different in Parent and in Child?
You fork() before you create the shared memory with the key IPC_PRIVATE, so both processes create their own shared memory and don't actually share it.
If you remove the =fork() from
pid_t pid=fork(), w;
and insert
pid = fork();
somewhere after the shmget call, it works the way you expect, since the child process will inherit the shared memory identifier from the parent and not create a different one.

Why unnamed semaphore doesn't change when used in shared memory?

I have to make 2 processes (server/client) that can access the same shared memory. I send the keys of shared memory via UNIX sockets between the server and the client. Then, I create the shared memory segment, and use unnamed semaphores to sychronize the server/client. As I think, I do everything right, but when I run the client process I can see that the semaphore isn't even initialized!
server.c sample:
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>
#include <errno.h>
sem_t *semaphore;
int main(int argc, char **argv){
//...making the connections here
// M is the number of semaphores i will use
key_t key3;
int shmid3;
if ((shmid3 = shmget(key3, M*sizeof(sem_t), 0644 | IPC_CREAT)) == -1) {
perror("shmget3");
exit(1);
}
key3 = htonl(key3);
if (send(s2, (const char*)&key3, 4, 0) == -1) {
perror("send");
exit(1);
}
int i;
semaphore=(sem_t *)shmat(shmid3, (void *) 0, 0);
if (semaphore == (sem_t *)(-1)) perror("shmat");
for(i=0;i<M;i++) if(sem_init(&semaphore[i], 1, 1)!=0) perror("sem_init");
//..do some stuff...
sleep(3);
for(i=0;i<M;i++) sem_destroy( &semaphore[i] );
if (shmdt(semaphore) == -1) {
perror("shmdt");
exit(1);
}
shmctl(shmid3, IPC_RMID, NULL);
//close connection...
}
client.c sample:
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>
#include <errno.h>
sem_t *semaphore;
int main(int argc, char **argv){
//...making the connections here
// M is the number of semaphores i will use
key_t key3;
n = recv(s, &key3, 4, 0);
if (n < 0) {
perror("recv");
}
key3 = ntohl(key3);
int shmid3;
if ((shmid3 = shmget(key3, M*sizeof(sem_t), 0644 )) == -1) {
perror("shmget3");
exit(1);
}
semaphore=(sem_t *)shmat(shmid3, (void *) 0, 0);
if (semaphore == (sem_t *)(-1)) perror("shmat");
int value;
sleep(1);
sem_getvalue(&semaphore[0], &value);
printf("\n[%d]\n",value); //always prints 0
//...do stuff...
if (shmdt(semaphore) == -1) {
perror("shmdt");
exit(1);
}
//close connection...
}
There isn't something wrong with the UNIX connection because I share and other memory segments, and they work just fine. I also tried changing the pshared argument of sem_initbut still nothing changes in the client.
I actualy want to use the semaphores in clinet's threads(M), but I see that they do not initialize even in the main process.
(Adapting from troubleshooting in the comments...)
The uninitialized key_t key3 happens to be initialized to the value IPC_PRIVATE, which means that a new shared memory segment is created for each caller of shmget(). The key should be explicitly initialized (in this case as by ftok()).

Resources