下面程式的功能是,創建一片共享記憶體,讓父行程和子行程都往里面寫資料,但是要求,父行程或者子行程寫完后,另一個行程才能開始寫,所有就需要同步,
關鍵點
-
mutex占用的記憶體空間必須是共享記憶體
-
必須把mutexaddr的屬性設定成PTHREAD_PROCESS_SHARED
-
int** shmptr2占用的記憶體空間必須是共享記憶體,它保存第一片共享記憶體的指標,移動到哪里了,
目的是,一個行程寫完共享記憶體后,另一個行程要知道它寫道哪里了,好接著寫,不然的話,就把上一個行程寫的內容給覆寫了,
所謂的共享記憶體
這片記憶體是在內核空間的,所以子行程不復制這片記憶體;如果不是共享記憶體,是父行程里的記憶體,那么子行程則復制它,
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <string.h>
int main()
{
pid_t pid;
int shmid;
int* shmptr;
int* tmp;
int err;
pthread_mutexattr_t mattr;
//創建mutex的屬性
if((err = pthread_mutexattr_init(&mattr)) < 0)
{
printf("mutex addr init error:%s\n", strerror(err));
exit(1);
}
//讓mutex可以同步多個行程
//mutex的默認屬性是同步執行緒的,所有必須要有此行代碼
if((err = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED)) < 0)
{
printf("mutex addr get shared error:%s\n", strerror(err));
exit(1);
}
//注意:這里是個大坑,這里的mutex必須是用共享記憶體的方式創建,目的是父行程和子行程可以共用此mutex,
//否則,父行程的mutex就是父行程的,子行程的mutex就是子行程的,不能達到同步的作用,
pthread_mutex_t* m;
int mid = shmget(IPC_PRIVATE, sizeof(pthread_mutex_t), 0600);
m = (pthread_mutex_t*)shmat(mid, NULL, 0);
//使用mutex的屬性,創建mutex
if((err = pthread_mutex_init(m, &mattr)) < 0)
{
printf("mutex mutex init error:%s\n", strerror(err));
exit(1);
}
//創建一個共享記憶體區域,讓父行程和子行程往里寫資料,
if((shmid = shmget(IPC_PRIVATE, 1000, IPC_CREAT | 0600)) < 0)
{
perror("shmget error");
exit(1);
}
//取得指向共享記憶體的指標
if((shmptr = shmat(shmid, 0, 0)) == (void*)-1)
{
perror("shmat error");
exit(1);
}
tmp = shmptr;
//創建一個共享記憶體,保存上面共享記憶體的指標
int shmid2;
int** shmptr2;
if((shmid2 = shmget(IPC_PRIVATE, 20, IPC_CREAT | 0600)) < 0)
{
perror("shmget2 error");
exit(1);
}
//取得指向共享記憶體的指標
if((shmptr2 = shmat(shmid2, 0, 0)) == (void*)-1)
{
perror("shmat2 error");
exit(1);
}
//讓shmptr2指向共享記憶體id為shmid的首地址,
*shmptr2 = shmptr;
if((pid = fork()) < 0)
{
perror("fork error");
exit(1);
}
else if(pid == 0)
{
//從此處開始給mutex加鎖,如果加鎖成功,則此期間,父行程無法取得鎖
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
{
//從此處開始給mutex加鎖,如果加鎖成功,則此期間,子行程無法取得鎖
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);
}
}
//銷毀子行程
wait(NULL);
//查看共享記憶體的值
for(int i = 0; i < 70; ++i)
{
printf("%d ", tmp[i]);
}
printf("\n");
//銷毀mutex的屬性
pthread_mutexattr_destroy(&mattr);
//銷毀mutex
pthread_mutex_destroy(m);
exit(0);
}
c/c++ 學習互助QQ群:877684253
本人微信:xiaoshitou5854

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/40816.html
標籤:C
上一篇:[題記]序列計數-藍橋杯
