Saya menggunakan pthreads untuk membuat beberapa utas. Masing-masing utas pada satu titik mencoba menggunakan get_posts()
sebagai berikut:
$args = array(
'post_type' => 'post',
'post_status' => 'any'
);
$posts_list = get_posts($args);
Namun saya berakhir dengan crash berikut:
HP Fatal error: Call to a member function get() on a non-object in C:\dev\wordpress\wp-includes\cache.php on line 123
PLEASE NOTE ketika saya melakukan get_posts()
panggilan yang sama di bagian kode yang tidak berulir, saya tidak mengalami crash.
Sekarang, pertanyaan saya, bagaimana cara menelepon get_posts()
dari dalam thread pthread ? Dan jika saya tidak bisa melakukan itu, apa alternatifnya?
Terima kasih.
Memperbarui
Berikut ini contoh kode
class My_Thread extends Thread {
public function run() {
/* DO SOME STUFF HERE */
$args = array(
'post_type' => 'post',
'post_status' => 'any'
);
$posts_list = get_posts($args); // <------ This is causing the crash
}
}
// Create a array
$threads = array();
//Iniciate Miltiple Thread
foreach ( range("A", "C") as $i ) {
$threads[] = new My_Thread($i);
}
// Start The Threads
foreach ($threads as $thread) {
$thread->start();
}
get_posts()
panggilan yang sama di bagian kode yang tidak di-thread, saya tidak mengalami crash "; jadi tidak masalah denganget_posts($args)
panggilan saya . Selain itu, tidak ada kode yang perlu dilindungi pada saat ini, saya hanya membaca dari DB WordPressget_posts($args)
.Jawaban:
Karena ada begitu banyak upvotes untuk pertanyaan tersebut, meskipun masalah multithreading terlalu luas untuk format jawaban, saya akan mencoba menjelaskan mengapa Anda tidak boleh menggunakan wordpress API dengan cara multithreaded ....
TL; DR - PHP tidak diasumsikan multithreading siap, masalahnya bukan PHP itu sendiri tetapi terutama perpustakaan yang digunakannya. Inilah sebabnya mengapa disarankan untuk tidak menggunakan mode eksekusi multithreaded di apache walaupun secara teori seharusnya lebih cepat. Untuk menambah masalah lapisan yang mendasarinya tidak siap multithread, inti wordpress melanggar persyaratan paling mendasar multithread- tidak ada akses gratis ke global.
Apa masalah dengan global dalam lingkungan multithreaded? mari kita asumsikan kita memiliki kode yang terlihat naif
Meskipun hanya satu liner, itu bukan operasi atom untuk CPU, dan dibutuhkan beberapa instruksi tingkat mesin untuk menjalankannya secara aktual. Sesuatu seperti
Sekarang mari kita asumsikan kita memiliki dua utas AB yang memanggil
inc()
pada "waktu yang sama" (jelas dengan hanya satu CPU tidak ada yang namanya waktu yang sama), dan bahwa nilai awal $ g adalah 0, berapakah nilai $ g setelah kedua utas selesai? Ini akan tergantung pada bagaimana OS menangani multithreading, kapan ia beralih di antara utas. Dalam OS gaya "lama" itu adalah tugas utas untuk mendeklarasikan dengan memanggil API bahwa kontrol dapat diambil darinya, tetapi itu menyebabkan banyak masalah dengan proses perilaku buruk mengunci sistem karenanya dalam "modern" OS yang diambil OS kontrol kapan pun rasanya seperti itu. Dalam kehidupan nyata hasil kode adalah $ g akan memiliki nilai 2, tetapi ada juga kemungkinan berikutDalam konteks A
Hasil akhirnya adalah $ g memiliki nilai 1.
Jelas global bukan satu-satunya masalah dan penanganan input dan output juga merupakan inti untuk masalah mutithreading.
Dalam kode multithreading yang tepat Anda menggunakan kunci / mutex / semaphore / pipa / socket .... untuk membuat serial akses ke sumber daya global tersebut untuk memastikan akan ada hasil yang dapat diprediksi untuk operasi. Wordpress tidak melakukan itu.
Sial, wordpress bahkan bukan multi-proses yang aman. Sebagian besar waktu berlalu begitu saja karena skema DB dibangun dengan cara yang dalam penggunaan kehidupan nyata mencegah kebutuhan untuk memodifikasi data yang sama dari proses yang berbeda (posting yang berbeda memiliki baris yang berbeda dan tidak berbagi data), tetapi lihatlah kode sidebar / widget dan coba bayangkan apa yang akan terjadi jika dua admin akan mencoba menambahkan widget yang berbeda pada waktu yang bersamaan. Karena ini akan memerlukan manipulasi dari satu opsi tertentu, hasil akhirnya dapat berupa widget yang ditambahkan atau hanya salah satunya.
Kembali ke multithrading. Dalam unix, tidak seperti windows, biaya tambahan untuk menghasilkan suatu proses alih-alih thread dapat diabaikan, karenanya menggunakan
wp_remote_get
dengan beberapa url khusus untuk memanggil "thread" tambahan adalah hal yang sangat sah untuk dilakukan dan menghindari hampir semua jebakan yang terkait dengan multithreading.sumber