![](/img/trans.png)
[英]Should child class override the constructors if they have identical parameter as the parent class?
[英]Why do objects in parent/child processes have identical addresses?
我對以下代碼有兩個問題:
守則 :
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
int main(int argc, char **argv)
{
sem_t sem;
int var = 0;
/* create, initialize semaphore */
if( sem_init(&sem,1,1) < 0)
{
perror("semaphore initilization");
exit(0);
}
int pid = fork();
static const size_t loopLen = 5;
if (0 == pid)
{ /* child process */
for (size_t i = 0; i < loopLen; ++i)
{
sem_wait(&sem);
std::string str("Child");
std::cout << str << " process: &var(" << (void*)(&var) << ") var(" << var++ << ") &sem(" << (void*)(&sem) << ")" << std::endl;
sem_post(&sem);
}
}
else
{ /* parent process */
for (size_t i = 0; i < loopLen; ++i)
{
sem_wait(&sem);
std::string str("Parent");
std::cout << str << " process: &var(" << (void*)(&var) << ") var(" << var++ << ") &sem(" << (void*)(&sem) << ")" << std::endl;
sem_post(&sem);
}
}
}
輸出 :
Parent process: &var(0xffffcbdc) var(0) &sem(0xffffcbe0)
Child process: &var(0xffffcbdc) var(0) &sem(0xffffcbe0)
Parent process: &var(0xffffcbdc) var(1) &sem(0xffffcbe0)
Child process: &var(0xffffcbdc) var(1) &sem(0xffffcbe0)
Parent process: &var(0xffffcbdc) var(2) &sem(0xffffcbe0)
Child process: &var(0xffffcbdc) var(2) &sem(0xffffcbe0)
Parent process: &var(0xffffcbdc) var(3) &sem(0xffffcbe0)
Child process: &var(0xffffcbdc) var(3) &sem(0xffffcbe0)
Parent process: &var(0xffffcbdc) var(4) &sem(0xffffcbe0)
Child process: &var(0xffffcbdc) var(4) &sem(0xffffcbe0)
問題 :
從父進程和子進程打印時,為什么var
和sem
的地址相同? 我知道子進程獲取了父內存空間內容的副本 ,但我認為進程有獨立且不同的地址空間,因此沒有變量會在同一個內存位置 - 但這個輸出似乎表明不是這樣。
問題 :
這段代碼實際上是在同步兩個進程嗎? 我持懷疑態度。 雖然我用pshared
標志非零調用sem_init
,但它似乎再次是子進程應該獲取信號量的副本 。 我沒有看到sem
在父進程和子進程之間“共享”的機制:信號量沒有命名,我不明白在父進程和子進程之間如何共享信號量。 我懷疑每個進程只是獲取並釋放自己的信號量“副本”,但我不確定。
謝謝。
關於地址,這是因為子進程最初是父進程的完全重復 。 精確復制包括(虛擬)內存映射。 閱讀fork
手冊頁以獲取更多信息。
關於信號量,如果你閱讀sem_init
手冊頁,你會看到
如果
pshared
非零,那么信號量在進程之間共享,並且應該位於共享內存的區域中
這個位於共享內存中的位置由你來處理,但這並不是你自動完成的。
除了SingerOfTheFall的答案之外,我想補充說fork(2)
制作了父進程的精確副本 - 相同的內存映射,相同的信號掩碼,相同的文件描述符表 - 所以你實際上得到了你的進程的真實副本。
這些進程確實有不同的地址空間,但是為了理解為什么修改其中一個進程不會影響另一個進程,你應該記住虛擬和物理地址之間的區別以及所有進程(甚至是amd64上的內核)在虛擬地址空間中執行。
長話短說 - 簡而言之,CPU中有對應表(稱為頁表),每當您嘗試訪問給定地址時,CPU都會查找有問題地址的實際物理地址。 內核為每個進程填充頁表,並為每個進程提供相同的地址(如果未啟用ASLR)。
我無法確定為什么父母和孩子之間共享信號量,但如果你的初始化是正確的,那么它就不應該從外部世界獲得。
參看
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.