The function of the following program is to create a piece of shared memory, so that both the parent process and the child process can write data to it. However, it is required that another process can start to write after the parent process or the child process has finished writing, and all of them need to be synchronized.
Key points
-
The memory space occupied by mutex must be shared memory
-
The mutexaddr property must be set to pthread_ PROCESS_ SHARED
-
The memory space occupied by int * * shmptr2 must be shared memory. It holds the pointer to the first piece of shared memory and where it moved.
The purpose is that after one process finishes writing shared memory, the other process should know where it has written, so that it can continue to write. Otherwise, it will cover the content written by the previous process.
So called shared memory
This piece of memory is in the kernel space, so the child process does not copy this piece of memory; if it is not shared memory, it is the memory in the parent process, then the child process copies it.
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
pid_t pid;
int shmid;
int* shmptr;
int* tmp;
int err;
pthread_mutexattr_t mattr;
//Create mutex properties
if((err = pthread_mutexattr_init(&mattr)) < 0)
{
printf("mutex addr init error:%s\n", strerror(err));
exit(1);
}
//Let mutex synchronize multiple processes
//The default property of mutex is synchronous thread, all must have this line of code
if((err = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED)) < 0)
{
printf("mutex addr get shared error:%s\n", strerror(err));
exit(1);
}
//Note: This is a big pit. The mutex here must be created in the way of shared memory, so that the parent process and the child process can share this mutex.
//Otherwise, the mutex of the parent process is the mutex of the parent process, and the mutex of the child process is the mutex of the child process.
pthread_mutex_t* m;
int mid = shmget(IPC_PRIVATE, sizeof(pthread_mutex_t), 0600);
m = (pthread_mutex_t*)shmat(mid, NULL, 0);
//Use mutex's properties to create mutex
if((err = pthread_mutex_init(m, &mattr)) < 0)
{
printf("mutex mutex init error:%s\n", strerror(err));
exit(1);
}
//Create a shared memory area for parent and child processes to write data to.
if((shmid = shmget(IPC_PRIVATE, 1000, IPC_CREAT | 0600)) < 0)
{
perror("shmget error");
exit(1);
}
//Gets a pointer to shared memory
if((shmptr = shmat(shmid, 0, 0)) == (void*)-1)
{
perror("shmat error");
exit(1);
}
tmp = shmptr;
//Create a shared memory and save the pointer to the shared memory above
int shmid2;
int** shmptr2;
if((shmid2 = shmget(IPC_PRIVATE, 20, IPC_CREAT | 0600)) < 0)
{
perror("shmget2 error");
exit(1);
}
//Gets a pointer to shared memory
if((shmptr2 = shmat(shmid2, 0, 0)) == (void*)-1)
{
perror("shmat2 error");
exit(1);
}
//Let shmptr2 point to the first address of shared memory ID shmid.
*shmptr2 = shmptr;
if((pid = fork()) < 0)
{
perror("fork error");
exit(1);
}
else if(pid == 0)
{
//Start to lock mutex from here. If the lock is successful, the parent process cannot obtain the lock during this period
if((err = pthread_mutex_lock(m)) < 0)
{
printf("lock error:%s\n", strerror(err));
exit(1);
}
for(int i = 0; i < 30; ++i)
{
**shmptr2 = i;
(*shmptr2)++;
}
if((err = pthread_mutex_unlock(m)) < 0)
{
printf("unlock error:%s\n", strerror(err));
exit(1);
}
exit(0);
}
else
{
//Lock mutex from this point. If the lock is successful, the child process cannot obtain the lock during this period
if((err = pthread_mutex_lock(m)) < 0)
{
printf("lock error:%s\n", strerror(err));
exit(1);
}
for(int i = 10; i < 42; ++i)
{
**shmptr2 = i;
(*shmptr2)++;
}
if((err = pthread_mutex_unlock(m)) < 0)
{
printf("unlock error:%s\n", strerror(err));
exit(1);
}
}
//Destroy child process
wait(NULL);
//View the value of shared memory
for(int i = 0; i < 70; ++i)
{
printf("%d ", tmp[i]);
}
printf("\n");
//Destroy mutex properties
pthread_mutexattr_destroy(&mattr);
//Destroy mutex
pthread_mutex_destroy(m);
exit(0);
}
C / C + + Learning QQ group: 877684253