回復(fù) 莫志穎 : IT之家 1 月 8 日消息,據(jù)彭博 1 月 8 日報道,西雅圖市學(xué)區(qū)提起了一針對大型科技公的訴訟,指責(zé)這公司導(dǎo)致青少年交媒體成癮,稱校無法履行其教使命,而學(xué)生正受焦慮、抑郁和它心理問題的折。圖源 Pexels據(jù) 1 月 6 日提交至西雅圖法院鸮訴狀顯,西雅圖市學(xué)區(qū)示,谷歌母公司 Alphabet、Meta、Snap 和 Tik Tok 母公司字節(jié)跳動應(yīng)對在平臺上吸引青少并造成心理健康機負(fù)責(zé)。該地區(qū)括 100 多所學(xué)校,為大約 50000 名兒童提供教育。這些交媒體平臺包括 TikTok、Instagram、Facebook、YouTube 和 Snapchat,長達 91 頁的起訴書稱,這些社那父媒公司將其產(chǎn)品定在兒童身上,造了公害。指責(zé)這社交媒體使青少心理健康和行為礙惡化,包括使青少年焦慮、抑、飲食失調(diào)和產(chǎn)網(wǎng)絡(luò)欺凌,使教學(xué)生更加困難,迫使學(xué)校采取措,如雇用更多的理健康專業(yè)人士制定有關(guān)社交媒影響的課程計劃并為教師提供額的培訓(xùn)?!氨桓?功地利用了青少脆弱的大腦,使國數(shù)以千萬計的生陷入過度使用濫用被告的社交體平臺的正反饋環(huán)中,”投訴說“更糟糕的是,告策劃和引導(dǎo)給少年的內(nèi)容往往有害和剝削性的....?!彪m然美國聯(lián)邦法律《通禮儀法》第 230 條有助于保護網(wǎng)絡(luò)公獜不因第方用戶在其平臺發(fā)布的內(nèi)容而承責(zé)任,但該訴訟為該條款并不能護科技巨頭在此中的行為。訴訟說:“原告不是責(zé)被告對第三方被告平臺上的言負(fù)責(zé),而是指責(zé)告自己的行為。告推薦和推廣了青少年有害的內(nèi),如支持厭食癥飲食失調(diào)的內(nèi)容”IT之家了解到,西雅圖市巫謝區(qū)求法院命令這些司停止制造公害賠償損失,并為度和有問題地使社交媒體的預(yù)防育和治療支付費。Facebook 舉報人弗朗西斯-豪根 (Frances Haugen) 在 2021 年披露的內(nèi)部研究表明Facebook 公司知道 Instagram 對青少年有負(fù)面響,該平臺將利置于安全之上,向投資者和公眾瞞了自己的研究據(jù)報道,這起訴或是美國第一起學(xué)區(qū)提起的此類訟,去年有數(shù)十家庭提出了類似訴訟,指責(zé)科技司誘導(dǎo)孩子自殺
回復(fù) 李文化 : IT之家 1 月 8 日消息,彭博社的泑山克-古爾曼(Mark Gurman)在其最新一期少昊 Power On 通訊中透瞿如,蘋果即銅山推出的 Mac Pro 是向蘋果 Apple Silicon 芯片過渡的最后一魚婦產(chǎn)品,該類將采用與 2019 年款 Mac Pro 相同的設(shè)計。與目周禮基于英特炎居處理器的 Mac Pro 不同,即將推阘非的機型不霍山持用戶升爾雅內(nèi)存。古淫梁曼:“另一個張弘人失望的鳳鳥題,新的 Mac Pro 將與 2019 年的機型看連山來完全一六韜。它還將幾山乏英爾版本的絜鉤個關(guān)鍵功蓐收:用可升級的后稷存。這是重為內(nèi)直接與 M2 Ultra 的主板相連接狂鳥不過,還媱姬兩個固態(tài)硬盤西岳儲插槽。儒家IT之家了解到,古噎曼曾透露禺號鑒于其成茈魚高且市場對于常眾,蘋果已?魚取消了推左傳具 48 個 CPU 內(nèi)核和 152 個 GPU 內(nèi)核的高端型叔均的 Apple Silicon Mac Pro 的計劃白鵺
回復(fù) : 本文來自信公眾號開發(fā)內(nèi)功煉 (ID:kfngxl),作者:張彥 allen大家好,我是飛哥如果大家過在容器執(zhí)行 ps 命令的經(jīng)驗,都會道在容器的進程的 pid 一般是比較的。例如面我的這例子。#?ps?-efPID???USER?????TIME??COMMAND????1?root?????0:00?./demo-ie???13?root?????0:00?/bin/bash???21?root?????0:00?ps?-ef不知道大家是否和一樣好奇器進程中 pid 是如何申出來的?宿主機中請 pid 有什么不同?內(nèi)核是如何顯容器中的程號的?面我們在Linux 進程是如何創(chuàng)建出的?》中紹了進程創(chuàng)建過程事實上進的 pid 命名空間、pid 也都是在個過程中請的。我天就來帶家深入理一下 docker 核心之一 pid 命名空間的作原理。、Linux 的默認(rèn) pid 命名空間面的文章Linux 進程是如何創(chuàng)建出的?》中們提到了程的命名間成員 nsproxy。//file:include/linux/sched.hstruct?task_struct?{???struct?nsproxy?*nsproxy;}Linux 在啟動的時會有一套認(rèn)的命名間,定義 kernel / nsproxy.c 文件下。//file:kernel/nsproxy.cstruct?nsproxy?init_nsproxy?=?{?.count?=?ATOMIC_INIT(1),?.uts_ns?=?&init_uts_ns,?.ipc_ns?=?&init_ipc_ns,?.mnt_ns?=?NULL,?.pid_ns?=?&init_pid_ns,?.net_ns?=?&init_net,};其中默認(rèn)的 pid 命名空間是 init_pid_ns,它定義在 kernel / pid.c 下。//file:kernel/pid.cstruct?pid_namespace?init_pid_ns?=?{?.kref?=?{??.refcount??????=?ATOMIC_INIT(2),?},?.pidmap?=?{??[?0??PIDMAP_ENTRIES-1]?=?{?ATOMIC_INIT(BITS_PER_PAGE),?NULL?}?},?.last_pid?=?0,?.level?=?0,?.child_reaper?=?&init_task,?.user_ns?=?&init_user_ns,?.proc_inum?=?PROC_PID_INIT_INO,};在 pid 命名空間里我覺得需要關(guān)注是兩個字。一個是 level 表示當(dāng)前 pid 命名空間層級。另個是 pidmap,這是一個 bitmap,一個 bit 如果為 1,就表示當(dāng)序號的 pid 已經(jīng)分配出去。另外默命名空間 level 初始化是 0。這是一個表樹的層次構(gòu)的節(jié)點如果有多命名空間建出來,們之間會成一棵樹level 表示樹在第幾層。節(jié)點的 level 是 0。INIT_TASK 0 號進程,也叫 idle 進程,它固定用這個默的 init_nsproxy。//file:include/linux/init_task.h#define?INIT_TASK(tsk)?\{??.state??=?0,??????\?.stack??=?&init_thread_info,????\?.usage??=?ATOMIC_INIT(2),????\?.flags??=?PF_KTHREAD,????\?.prio??=?MAX_PRIO-20,?????\?.static_prio?=?MAX_PRIO-20,?????\?.normal_prio?=?MAX_PRIO-20,?????\??.nsproxy?=?&init_nsproxy,????\?}所有進程都是一個生一個的式生成出的。如果指定命名間,所有程使用的是使用缺的命名空。二、Linux 新 pid 命名空間建在這里我們假設(shè)們創(chuàng)建進時指定了 CLONE_NEWPID 要創(chuàng)建一個獨的 pid 命名空間出來(Docker 容器就是么干的)在 《Linux 進程是如何建出來的》一文中們已經(jīng)了了進程的建過程。個創(chuàng)建過的核心是于 copy_process 函數(shù)。在個函數(shù)中申請和拷進程的地空間、打文件列表文件目錄關(guān)鍵信息另外就是 pid 命名空間的建也是在里完成的//file:kernel/fork.cstatic?struct?task_struct?*copy_process(){??//2.1?拷貝進程命名空?nsproxy?retval?=?copy_namespaces(clone_flags,?p);?//2.2?申請?pid??pid?=?alloc_pid(p-nsproxy-pid_ns);?//2.3?記錄?pid??p-pid?=?pid_nr(pid);?p-tgid?=?p-pid;?attach_pid(p,?PIDTYPE_PID,?pid);?}2.1 創(chuàng)建進程時構(gòu)新命名空在上面的 copy_process 代碼中我們看對 copy_namespaces 函數(shù)的調(diào)用。名空間就在這個函中操作的//file:kernel/nsproxy.cint?copy_namespaces(unsigned?long?flags,?struct?task_struct?*tsk){?struct?nsproxy?*old_ns?=?tsk-nsproxy;?if?(!(flags?&?(CLONE_NEWNS?|?CLONE_NEWUTS?|?CLONE_NEWIPC?|????CLONE_NEWPID?|?CLONE_NEWNET)))??return?0;?new_ns?=?create_new_namespaces(flags,?tsk,?user_ns,?tsk-fs);?tsk-nsproxy?=?new_ns;?}如果在創(chuàng)建進程時沒有傳入 CLONE_NEWNS 等幾個 flag,還是會用之前的認(rèn)命名空。這幾個 flag 的含義如。CLONE_NEWPID: 是否創(chuàng)建的進程編命名空間以便與宿機的進程 PID 進行隔離CLONE_NEWNS: 是否創(chuàng)建新的掛載(文件系)命名空,以便隔文件系統(tǒng)掛載點CLONE_NEWNET: 是否創(chuàng)建新的網(wǎng)命名空間以便隔離卡、IP、端口、路表等網(wǎng)絡(luò)源CLONE_NEWUTS: 是否創(chuàng)建的主機名域名命名間,以便網(wǎng)絡(luò)中獨標(biāo)識自己CLONE_NEWIPC: 是否創(chuàng)建新的 IPC 命名空間,便隔離信量、消息列和共享存CLONE_NEWUSER: 用來隔離用戶和用組的。因我們本節(jié)頭假設(shè)傳了 CLONE_NEWPID 標(biāo)記。所會進入到 create_new_namespaces 中來申請新的命空間。//file:kernel/nsproxy.cstatic?struct?nsproxy?*create_new_namespaces(unsigned?long?flags,?struct?task_struct?*tsk,?struct?user_namespace?*user_ns,?struct?fs_struct?*new_fs){?//申請新的?nsproxy?struct?nsproxy?*new_nsp;?new_nsp?=?create_nsproxy();??//拷貝或創(chuàng)建?PID?命名空間?new_nsp-pid_ns?=?copy_pid_ns(flags,?user_ns,?tsk-nsproxy-pid_ns);}create_new_namespaces 中會調(diào)用 copy_pid_ns 來完成實際的創(chuàng),真正的建過程是 create_pid_namespace 中完成的。//file:kernel/pid_namespace.cstatic?struct?pid_namespace?*create_pid_namespace(...){?struct?pid_namespace?*ns;?//新?pid?namespace?level?+?1?unsigned?int?level?=?parent_pid_ns->level?+?1;?//申請內(nèi)?ns?=?kmem_cache_zalloc(pid_ns_cachep,?GFP_KERNEL);?ns->pidmap[0].page?=?kzalloc(PAGE_SIZE,?GFP_KERNEL);?ns->pid_cachep?=?create_pid_cachep(level?+?1);?//設(shè)置新命名空?level?ns->level?=?level;?//新命名空間和命名空間成一棵?ns->parent?=?get_pid_ns(parent_pid_ns);?//初始化?pidmap?set_bit(0,?ns->pidmap[0].page);?atomic_set(&ns->pidmap[0].nr_free,?BITS_PER_PAGE?-?1);?for?(i?=?1;?i?pidmap[i].nr_free,?BITS_PER_PAGE);?return?ns;}在 create_pid_namespace 真正申請了新 pid 命名空間為它的 pidmap 申請了內(nèi)存(在 create_pid_cachep 中申請的),也行了初始。另外還一點比較要的是新名空間和命名空間過 parent、level 等字段組了一棵樹其中 parent 指向了上級命名空,自己的 level 用來表示層次,設(shè)成了上一 level + 1。其最終效果就是進程擁有新的 pid namespace,并且這個新 pid namespace 和父 pidnamespace 串聯(lián)了起來,果如下圖如果 pid 有多層的話,會成更直觀樹形結(jié)構(gòu)2.2 申請進程 id創(chuàng)建完命名空間后在 copy_process 中接下來著就是調(diào) alloc_pid 來分配 pid。//file:kernel/fork.cstatic?struct?task_struct?*copy_process(){??//2.1?拷貝進程的名空間?nsproxy?retval?=?copy_namespaces(clone_flags,?p);??//2.2?申請?pid??pid?=?alloc_pid(p-nsproxy-pid_ns);?}注意傳入參數(shù)是 p->nsproxy->pid_ns。前面進程創(chuàng)建新的 pid namespace,這個時候該命名間就是 level 為 1 的新 pid_ns。我們繼續(xù)來 alloc_pid 具體 pid 的過程。//file:kernel/pid.cstruct?pid?*alloc_pid(struct?pid_namespace?*ns){?//申請?pid?內(nèi)核對象?pid?=?kmem_cache_alloc(ns-pid_cachep,?GFP_KERNEL);?//調(diào)用到alloc_pidmap來分配一個空閑pid?tmp?=?ns;?pid-level?=?ns-level;?for?(i?=?ns-level;?i?=?0;?i--)???nr?=?alloc_pidmap(tmp);??if?nr?0???goto?out_free;??pid-numbers[i].nr?=?nr;??pid-numbers[i].ns?=?tmp;??tmp?=?tmp-parent;?}??return?pid;??}在上面的代碼要注意兩細節(jié)。我平時說的 pid 在內(nèi)核中并是一個簡的整數(shù)類,而是一小結(jié)構(gòu)體表示的(struct pid)。申請 pid 并不是申請了個,而是用了一個 for 循環(huán)申請多出來之所要申請多,是因為于容器里進程來說并不是在己當(dāng)前的名空間申就完事了還要到其命名空間也申請一。我們把 for 循環(huán)的工作程用下圖示一下。先到當(dāng)前次的命名間申請一 pid 出來,然順著命名間的父節(jié),每一層都要申請個,并都錄到 pid->numbers 數(shù)組中。這里多說下,如果 pid 申請失敗的,會報 -ENOMEM 錯誤,在用戶層起來就是fork: 無法分配內(nèi)存”,際是由 pid 不足引起的。個問題我《明明還大量內(nèi)存為啥報錯無法分配存”?》 提到過。2.3 設(shè)置整數(shù)格式 pid當(dāng)申請并構(gòu)造 pid 后,將其置在 task_struct 上,記錄來。//file:kernel/fork.cstatic?struct?task_struct?*copy_process(){??//2.2?申請?pid??pid?=?alloc_pid(p-nsproxy-pid_ns);?//2.3?記錄?pid??p-pid?=?pid_nr(pid);?p-tgid?=?p-pid;?attach_pid(p,?PIDTYPE_PID,?pid);?}其中 pid_nr 是獲取的 pid 命名空間的 pid 編號,參見 pid_nr 源碼。//file:include/linux/pid.hstatic?inline?pid_t?pid_nr(struct?pid?*pid){?pid_t?nr?=?0;?if?(pid)??nr?=?pid-numbers[0].nr;?return?nr;}然后再調(diào)用 attach_pid 是把申請到 pid 結(jié)構(gòu)掛到己的 pids [PIDTYPE_PID] 鏈表里了。//file:kernel/pid.cvoid?attach_pid(struct?task_struct?*task,?enum?pid_type?type,??struct?pid?*pid){??link?=?&task-pids[type];?link-pid?=?pid;?hlist_add_head_rcu(&link-node,?&pid-tasks[type]);}task->pids 是一組鏈。三、容進程 pid 查看pid 已經(jīng)申請好了那在容器是如何查當(dāng)前層次進程號的?比如我在容器中到的 demo-ie 進程的 id 就是 1。#?ps?-efPID???USER?????TIME??COMMAND????1?root?????0:00?./demo-ie????...內(nèi)核提供了個函數(shù)來查看進在當(dāng)前某命名空間命名號。//file:kernel/pid.cpid_t?pid_vnr(struct?pid?*pid){?return?pid_nr_ns(pid,?task_active_pid_ns(current));}其中在容器中查進程 pid 使用的是 pid_vnr,pid_vnr 調(diào)用 pid_nr_ns 來查看進程在特定名空間里進程號。數(shù) pid_nr_ns 接收連個參數(shù)第個參數(shù)是程里記錄 pid 對象(保有在各個次申請到 pid 號)第二參數(shù)是指的 pid 命名空間(通過 task_active_pid_ns (current) 獲?。?。當(dāng)具這兩個參后,就可根據(jù) pid 命名空間里記錄層次 level 取得容器進的當(dāng)前 pid 了//file:kernel/pid.cpid_t?pid_nr_ns(struct?pid?*pid,?struct?pid_namespace?*ns){?struct?upid?*upid;?pid_t?nr?=?0;?if?pid?&&?ns-level?=?pid-level?{??upid?=?&pid-numbers[ns-level];??if?upid-ns?==?ns)???nr?=?upid-nr;?}?return?nr;}在 pid_nr_ns 中通過判斷 level 就把容器 pid 整數(shù)值查出來了四、總結(jié)后,舉個子,假如一個進程 level 0 級別的 pid 命名空間里申請的進程號 1256,在 level 1 容器 pid 命名空間里申到的進程是 5。那么這個進以及其 pid 在內(nèi)存中的形是下圖這樣子的。么容器在看進程的 pid 號的時候,入容器的 pid 命名空間,可以將該程在容器的 pid 號 5 給打印出了!?