Rumah >Operasi dan penyelenggaraan >operasi dan penyelenggaraan linux >Pemahaman mendalam tentang penciptaan dan penggunaan benang pengaturcaraan sistem-(pthread) Linux
Artikel ini membawa anda pengetahuan tentang penciptaan dan penggunaan benang dalam Linux, saya harap ia akan membantu anda.
Perbezaan antara benang dan proses (1) Proses: Ia adalah unit terkecil penjadualan sistem pengendalian. Di bawah Linux, anda boleh melihat maklumat terperinci proses melalui arahan seperti ps dan atas. (2) Thread: Ia adalah unit terkecil penjadualan proses Setiap proses mempunyai utas utama. Perkara utama yang melakukan perkara dalam proses adalah benang.
(3) Dalam keseluruhan sistem, ID proses ialah pengecam unik, dan pengurusan proses dicapai melalui PID. Setiap kali proses dibuat, kernel akan mencipta struktur untuk menyimpan semua maklumat tentang proses Setiap nod yang menyimpan maklumat proses juga menyimpan PIDnya sendiri. Apabila anda perlu mengurus proses, anda boleh menggunakan ID ini untuk mencapainya (seperti menghantar isyarat). Apabila proses anak tamat dan perlu dikitar semula (proses anak memanggil exit() untuk keluar atau kod dilaksanakan), ia perlu dilakukan melalui panggilan sistem tunggu() Proses mati yang tidak dikitar semula akan menjadi a proses zombi, dan entiti prosesnya tidak lagi wujud, tetapi Ia akan menduduki sumber PID, jadi kitar semula adalah perlu.
Untuk utas, jika anda ingin menamatkan secara aktif, anda perlu memanggil pthread_exit(), dan utas utama perlu memanggil pthread_join() untuk mengitar semula (dengan syarat benang tidak menetapkan "atribut detasmen") . Menghantar isyarat benang seperti benang juga melaksanakan
komunikasi antara proses melalui ID benang: A. Memori dikongsi B. Baris gilir mesej C. Semaphore D. Paip bernama E. Paip tanpa nama F. Isyarat G. Fail H. Kaedah komunikasi antara benang soket: A. Mutex B. Kunci putaran C. Pembolehubah keadaan D. Kunci baca-tulis E. Isyarat benang F. Pembolehubah global
Kaedah komunikasi yang digunakan antara proses memerlukan penukaran Konteks kernel, sama ada untuk diakses dengan perkakasan (paip bernama, fail). Jadi kelajuan akan menjadi lebih perlahan. Jika benang menggunakan kaedah komunikasi uniknya sendiri, ia pada asasnya disiapkan dalam ruang prosesnya sendiri, dan tiada pensuisan, jadi kelajuan komunikasi akan menjadi lebih cepat. Dalam erti kata lain, sebagai tambahan kepada perbezaan jenis, kaedah komunikasi yang digunakan antara proses dan benang juga mempunyai perbezaan dalam kelajuan.
Nota: Apabila proses yang menjalankan berbilang utas menangkap isyarat, hanya utas utama akan disekat dan utas anak lain akan terus dilaksanakan tanpa menjejaskannya.
2.1 Mencipta benang
pthread_create ialah fungsi untuk mencipta benang dalam sistem pengendalian Unix (Unix, Linux , dsb.). Anda perlu menentukan perpustakaan pautan semasa menyusun: -prototaip fungsi lpthread
#include <pthread.h> int pthread_create ( pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg );
Pengenalan parameter
Parameter pertama ialah penunjuk kepada pengecam benang. Parameter kedua digunakan untuk menetapkan sifat benang. NULL boleh diisi secara lalai. Parameter ketiga ialah alamat permulaan fungsi berjalan benang. Parameter terakhir ialah parameter untuk menjalankan fungsi. Tiada parameter diperlukan dan NULL boleh diisi. Lihat bantuan fungsi di bawah Linux: # man pthread_create
Nilai pulangan: Jika urutan berjaya dibuat, 0 dikembalikan. Jika penciptaan benang gagal, nombor ralat dikembalikan. Selepas benang berjaya dibuat, parameter attr digunakan untuk menentukan pelbagai atribut benang. Benang yang baru dibuat mula berjalan dari alamat fungsi start_rtn Fungsi ini hanya mempunyai satu parameter penunjuk universal arg Jika lebih daripada satu parameter perlu dihantar ke fungsi kerja benang, maka parameter ini perlu dimasukkan ke dalam struktur. dan kemudian alamat struktur ini Diluluskan sebagai parameter arg.
Contoh:
#include <stdio.h> #include <pthread.h> //线程函数1 void *pthread_func1(void *arg) { while(1) { printf("线程函数1正在运行.....\n"); sleep(2); } } //线程函数2 void *pthread_func2(void *arg) { while(1) { printf("线程函数2正在运行.....\n"); sleep(2); } } int main(int argc,char **argv) { pthread_t thread_id1; pthread_t thread_id2; /*1. 创建线程1*/ if(pthread_create(&thread_id1,NULL,pthread_func1,NULL)) { printf("线程1创建失败!\n"); return -1; } /*2. 创建线程2*/ if(pthread_create(&thread_id2,NULL,pthread_func2,NULL)) { printf("线程2创建失败!\n"); return -1; } /*3. 等待线程结束,释放线程的资源*/ pthread_join(thread_id1,NULL); pthread_join(thread_id2,NULL); return 0; } //gcc pthread_demo_code.c -lpthread
2.2 Keluar dari thread
Benang menamatkan pelaksanaan dengan memanggil fungsi pthread_exit, sama seperti proses memanggil exit fungsi pada akhir. Fungsi fungsi ini adalah untuk menamatkan benang yang memanggilnya dan mengembalikan penunjuk ke objek.
Fungsi fungsi ini adalah untuk menamatkan benang yang memanggilnya dan mengembalikan penunjuk kepada objek Nilai pulangan boleh diperolehi melalui parameter kedua fungsi pthread_join.
Prototaip fungsi
#include <pthread.h> void pthread_exit(void *retval);
Analisis parameter Alamat pemulangan benang. Nota: Tindanan benang mesti dilepaskan apabila benang tamat, yang bermaksud fungsi benang mesti memanggil pthread_exit() untuk tamat, jika tidak, ia tidak akan dikeluarkan sehingga fungsi proses utama keluar
2.3 Menunggu untuk utas berakhir
Fungsi pthread_join() menunggu urutan yang ditentukan oleh utas berakhir dengan cara menyekat. Apabila fungsi kembali, sumber benang menunggu akan dituntut semula. Jika benang telah tamat, fungsi kembali serta-merta. Dan utas yang ditentukan oleh utas mestilah atribut boleh digabungkan (atribut gabungan). Prototaip fungsi
#include <pthread.h> int pthread_join(pthread_t thread, void **retval);
Parameter Parameter pertama: Pengecam benang, iaitu ID benang, mengenal pasti urutan unik. Parameter terakhir: penunjuk yang ditentukan pengguna yang digunakan untuk menyimpan alamat yang dikembalikan oleh urutan menunggu. Nilai pulangan 0 mewakili kejayaan. Jika gagal, nombor ralat dikembalikan. Contoh menerima nilai pulangan benang:
//退出线程 pthread_exit ("线程已正常退出"); //接收线程的返回值 void *pth_join_ret1; pthread_join( thread1, &pth_join_ret1);
2.4 Atribut pemisahan benang
创建一个线程默认的状态是joinable(结合属性),如果一个线程结束运行但没有调用pthread_join,则它的状态类似于进程中的Zombie Process(僵死进程),即还有一部分资源没有被回收(退出状态码),所以创建线程者应该pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源(类似于进程的wait,waitpid)。但是调用pthread_join(pthread_id)函数后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此。
pthread_detach函数可以将该线程的状态设置为detached(分离状态),则该线程运行结束后会自动释放所有资源。 函数原型
#include <pthread.h> int pthread_detach(pthread_t thread);
参数 线程标识符 返回值 0表示成功。错误返回错误码。 EINVAL线程并不是一个可接合线程。 ESRCH没有线程ID可以被发现。
2.5 获取当前线程的标识符
pthread_self函数功能是获得线程自身的ID。 函数原型
#include <pthread.h> pthread_t pthread_self(void);
返回值 当前线程的标识符。 pthread_t的类型为unsigned long int,所以在打印的时候要使用%lu方式,否则显示结果出问题。
2.6 自动清理线程资源
线程可以安排它退出时需要调用的函数,这样的函数称为线程清理处理程序。用于程序异常退出的时候做一些善后的资源清理。 在POSIX线程API中提供了一个pthread_cleanup_push()/pthread_cleanup_pop()函数用于自动释放资源。从pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动作(包括调用 pthread_exit()和异常终止)都将执行pthread_cleanup_push()所指定的清理函数。
注意:pthread_cleanup_push函数与pthread_cleanup_pop函数需要成对调用。 函数原型
void pthread_cleanup_push(void (*routine)(void *),void *arg); //注册清理函数 void pthread_cleanup_pop(int execute); //释放清理函数
参数 void (*routine)(void *) :处理程序的函数入口。 void *arg :传递给处理函数的形参。 int execute:执行的状态值。 0表示不调用清理函数。1表示调用清理函数。
导致清理函数调用的条件:
调用pthread_exit()函数
pthread_cleanup_pop的形参为1。 注意:return不会导致清理函数调用。
2.7 自动清理线程示例代码
#include <stdio.h> #include <pthread.h> #include <stdlib.h> //线程清理函数 void routine_func(void *arg) { printf("线程资源清理成功\n"); } //线程工作函数 void *start_routine(void *dev) { pthread_cleanup_push(routine_func,NULL); //终止线程 // pthread_exit(NULL); pthread_cleanup_pop(1); //1会导致清理函数被调用。0不会调用。 } int main(int argc,char *argv[]) { pthread_t thread_id; //存放线程的标识符 /*1. 创建线程*/ if(pthread_create(&thread_id,NULL,start_routine,NULL)!=0) { printf("线程创建失败!\n"); } /*2.设置线程的分离属性*/ if(pthread_detach(thread_id)!=0) { printf("分离属性设置失败!\n"); } while(1){} return 0; }
2.8 线程取消函数
pthread_cancel函数为线程取消函数,用来取消同一进程中的其他线程。
头文件: #include <pthread.h> 函数原型:pthread_cancel(pthread_t tid);
相关推荐:《Linux视频教程》
Atas ialah kandungan terperinci Pemahaman mendalam tentang penciptaan dan penggunaan benang pengaturcaraan sistem-(pthread) Linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!