GNU/Linux >> Znalost Linux >  >> Linux

Přístup k místnímu vláknu z jiného vlákna

Bohužel jsem nikdy nenašel způsob, jak to udělat.

Bez nějakého druhu init háčku vlákna se prostě nezdá být způsob, jak se dostat k tomuto ukazateli (krátké ASM hacky, které by byly závislé na platformě).


Pokud chcete lokální proměnné vlákna, které nejsou lokální, proč místo toho nepoužijete globální proměnné?

Důležité vysvětlení!

Nenavrhuji, abyste k nahrazení lokální proměnné vlákna používali jedinou globální. Navrhuji použít jediné globální pole nebo jinou vhodnou sbírku hodnot k nahrazení jedné lokální proměnné vlákna.

Samozřejmě budete muset zajistit synchronizaci, ale protože chcete vystavit hodnotu upravenou ve vláknu A vláknu B, nelze to obejít.

Aktualizace:

Dokumentace GCC na __thread říká:

Když je operátor address-of aplikován na lokální proměnnou podprocesu, vyhodnotí se za běhu a vrátí adresu aktuální instance této proměnné. Takto získanou adresu může použít jakékoli vlákno. Když vlákno skončí, všechny ukazatele na místní proměnné vlákna v tomto vláknu se stanou neplatnými.

Pokud tedy trváte na tom, že půjdete tímto způsobem, představuji si, že je možné získat adresu lokální proměnné vlákna z vlákna, ke kterému patří, hned po vytvoření vlákna. Pak byste mohli uložit ukazatel na toto paměťové místo do mapy (id vlákna => ukazatel) a umožnit ostatním vláknům přistupovat k proměnné tímto způsobem. To předpokládá, že vlastníte kód vytvořeného vlákna.

Pokud jste opravdu dobrodružní, můžete zkusit najít informace na ___tls_get_addr (začněte z tohoto PDF, na který odkazují výše uvedené dokumenty GCC). Ale tento přístup je tak silně specifický pro kompilátor a platformu a tak postrádá dokumentaci, že by měl způsobovat poplachy v hlavě každého.


Hledám to samé. Jak vidím, nikdo na vaši otázku neodpověděl poté, co jsem všemi způsoby prohledal web, dospěl jsem k následným informacím:předpokládá se kompilace pro gcc na linuxu (ubuntu) a pomocí -m64, segmentový registr gs má hodnotu 0. Skrytá část segmentu (držící lineární adresu) ukazuje na místní oblast specifickou pro vlákno. Tato oblast obsahuje na této adrese adresu této adresy ( 64 bitů ). Na nižších adresách jsou uloženy všechny lokální proměnné vlákna. Tato adresa je native_handle() .Takže abyste získali přístup k místním datům vláken, měli byste to udělat přes tento ukazatel.

Jinými slovy:(char*)&variable-(char*)myThread.native_handle()+(char*)theOtherThread.native_handle()

Kód, který demonstruje výše uvedené, za předpokladu g++,linux,pthreads je:

#include <iostream>
#include <thread>
#include <sstream>

thread_local int B=0x11111111,A=0x22222222;

bool shouldContinue=false;

void code(){
    while(!shouldContinue);
    std::stringstream ss;
    ss<<" A:"<<A<<" B:"<<B<<std::endl;
    std::cout<<ss.str();
}

//#define ot(th,variable) 
//(*( (char*)&variable-(char*)(pthread_self())+(char*)(th.native_handle()) ))

int& ot(std::thread& th,int& v){
    auto p=pthread_self();
    intptr_t d=(intptr_t)&v-(intptr_t)p;
    return *(int*)((char*)th.native_handle()+d);
}

int main(int argc, char **argv)
{       

        std::thread th1(code),th2(code),th3(code),th4(code);

        ot(th1,A)=100;ot(th1,B)=110;
        ot(th2,A)=200;ot(th2,B)=210;
        ot(th3,A)=300;ot(th3,B)=310;
        ot(th4,A)=400;ot(th4,B)=410;

        shouldContinue=true;

        th1.join();
        th2.join();
        th3.join();
        th4.join();

    return 0;
}

Linux
  1. Upravte Qt GUI z pracovního vlákna na pozadí

  2. Jak mohu zabránit uživateli v kopírování souborů na jiný pevný disk?

  3. Kopírování paketů z rozhraní do jiného

  1. Jak získat přístup k phpMyAdmin z cPanel

  2. Migrujte do Rackspace od jiného poskytovatele hostingu

  3. IPTables – Port na jinou IP a port (zevnitř)

  1. Jak zkopírovat nastavení z jednoho počítače do druhého?

  2. Je bezpečné forkovat z vlákna?

  3. Změřte provoz z protokolu přístupu Apache