Rumah > Tutorial sistem > LINUX > Artifak dalam Linux: Prinsip dan Aplikasi eventfd

Artifak dalam Linux: Prinsip dan Aplikasi eventfd

王林
Lepaskan: 2024-02-13 20:30:16
ke hadapan
748 orang telah melayarinya

Linux ialah sistem pengendalian berkuasa yang menyediakan banyak mekanisme komunikasi antara proses yang cekap, seperti paip, isyarat, baris gilir mesej, memori dikongsi, dsb. Tetapi adakah cara yang lebih mudah, lebih fleksibel dan lebih cekap untuk berkomunikasi? Jawapannya ya, itulah eventfd. eventfd ialah panggilan sistem yang diperkenalkan dalam Linux versi 2.6 Ia boleh digunakan untuk melaksanakan pemberitahuan acara, iaitu, untuk menyampaikan acara melalui deskriptor fail. eventfd mengandungi pembilang integer tidak bertanda 64-bit yang diselenggara oleh kernel Proses ini boleh membaca/menukar nilai pembilang dengan membaca/menulis deskriptor fail ini untuk mencapai komunikasi antara proses. Apakah kelebihan eventfd? Ia mempunyai ciri-ciri berikut:

Artifak dalam Linux: Prinsip dan Aplikasi eventfd

  • eventfd tidak perlu mencipta sebarang fail atau ruang memori tambahan, ia hanya memerlukan deskriptor fail
  • eventfd boleh digunakan bersama dengan mekanisme pemultipleksan seperti pilih, tinjauan pendapat dan epoll untuk mencapai pengaturcaraan dipacu acara yang cekap
  • eventfd boleh ditetapkan kepada mod bukan sekatan atau semaphore, memberikan semantik komunikasi yang berbeza
  • eventfd boleh merentas proses atau sempadan benang untuk mencapai tahap komunikasi yang berbeza.

Jadi, bagaimana eventfd berfungsi? Apakah senario aplikasi yang ada padanya? Artikel ini akan memperkenalkan eventfd artifak dari dua aspek: prinsip dan aplikasi.

Secara umumnya: Terdapat lima penyelesaian utama untuk komunikasi antara proses Linux: paip, baris gilir mesej, semafor, memori dikongsi dan soket.
Saya tidak begitu biasa dengan paip. Saya hanya tahu tentang batasan paip umum dan hubungan antara proses ibu bapa dan anak. Saya menolaknya pada mulanya kerana apa yang saya mahu lakukan adalah komunikasi antara proses yang bebas terhad kepada proses ibu bapa dan anak, tetapi dalam keadaan kernel Tidak pasti cara menggunakannya.
Saya tidak faham Baris Mesej langsung.
Inti semaphore ialah operasi atom pembolehubah kernel, tetapi antara muka hanya dicerminkan dalam keadaan pengguna, dan operasi PV semaphore nampaknya lebih kepada pengecualian bersama, dan bukannya mekanisme bangun pemberitahuan yang saya mahukan. .
Memori yang dikongsi lebih menyusahkan Antara muka hanya dalam mod pengguna Jika anda ingin berkongsi memori antara mod kernel dan mod pengguna, anda perlu menulis fail itu sendiri dan kemudian menyediakan antara muka mmap.
Soket hanya digunakan dengan tcp/udp af_inet dan dgram af_unix sebelum ini. Kernel tidak menyediakan antara muka yang jelas Walaupun anda boleh memanggilnya sendiri menggunakan fungsi seperti sock->ops->recvmsg Lagipun, anda perlu membina sendiri parameter input, yang masih terasa tidak selamat.

Satu-satunya perkara yang tinggal nampaknya ialah netlink Soket ini dengan jelas menyediakan fungsi penghantaran paket kernel, kerana ia mengeksport dengan jelas fungsi netlink_kernel_create, jadi fungsi keadaan kernel boleh menggunakan sock ini untuk menghantar paket. Tetapi satu ialah mod pengguna perlu mendaftarkan fungsi menerima paket, dan satu lagi ialah mod kernel masih perlu memasang skb untuk menghantar paket Ia masih terlalu rumit bagi saya yang hanya mahu bangun dengan pemberitahuan.

Jadi saya mencari lagi dan menemui artifak eventfd Antara komunikasi antara KVM dan Qemu, eventfd digunakan dengan hebat oleh Daniel Selepas menganalisis kod sumber dengan teliti, saya mendapati bahawa perkara ini adalah seperti namanya, semata-mata untuk pemberitahuan .
Sebagai fail (ada apa-apa dalam Linux yang bukan fail~~), struktur data_peribadi eventfd_ctx hanya mempunyai empat pembolehubah yang menyedihkan.

struct eventfd_ctx {
  struct kref kref;  /* 这个就不多说了,file计数用的,用于get/put */
  wait_queue_head_t wqh; /* 这个用来存放用户态的进程wait项,有了它通知机制才成为可能 */
/*
\* Every time that a write(2) is performed on an eventfd, the
\* value of the __u64 being written is added to "count" and a
\* wakeup is performed on "wqh". A read(2) will return the "count"
\* value to userspace, and will reset "count" to zero. The kernel
\* side eventfd_signal() also, adds to the "count" counter and
\* issue a wakeup.
*/
  __u64 count;  /* 这个就是一个技术器,应用程序可以自己看着办,read就是取出然后清空,write就是把value加上 */
  unsigned int flags;  /* 所有的file都有的吧,用来存放阻塞/非阻塞标识或是O_CLOEXEC之类的东西 */
};
  我之所以选用它是因为它有 eventfd_signal 这个特地为内核态提供的接口,下面的是注释。
 \* This function is supposed to be called by the kernel in paths that do not
 \* allow sleeping. In this function we allow the counter to reach the ULLONG_MAX
 \* value, and we signal this as overflow condition by returining a POLLERR to poll(2).
Salin selepas log masuk

Malah, akan lebih jelas jika anda melihat kod tersebut

int eventfd_signal(struct eventfd_ctx *ctx, int n)
{
  unsigned long flags;

  if (n return -EINVAL;
  spin_lock_irqsave(&ctx->wqh.lock, flags);
  if (ULLONG_MAX - ctx->count count);
  ctx->count += n;
  if (waitqueue_active(&ctx->wqh))
    wake_up_locked_poll(&ctx->wqh, POLLIN);
  spin_unlock_irqrestore(&ctx->wqh.lock, flags);

  return n;
}  
Salin selepas log masuk

Intinya bangun sekali, tanpa membaca atau menulis Bezanya eventfd_write ialah tiada blocking

Ini penggunaan khusus saya:
Keadaan kernel ialah modul yang mendaftarkan peranti misc dan mencipta benang kernel untuk berfungsi (parameternya ialah fail modul->private_data). Sediakan antara muka ioctl untuk proses mod pengguna untuk menyampaikan fd yang dicipta oleh eventfdnya sendiri, dan simpan dalam fail->data_pribadi yang boleh diakses oleh utas kernel.
Apabila keadaan kernel ingin memberitahu keadaan pengguna, eventfd_signal digunakan secara langsung Pada masa ini, urutan keadaan pengguna perlu meletakkan dirinya pada eventfd_ctx->wqh Terdapat dua penyelesaian, satu ialah memanggil baca untuk memanggil tinjauan pendapat. Jika ia adalah bacaan, eventfd_ctx->count akan dikosongkan kemudian dan boleh disekat kali seterusnya. Walau bagaimanapun, jika tinjauan pendapat digunakan, kiraan tidak dibersihkan selepas itu, menyebabkan tinjauan pendapat kembali serta-merta walaupun tiada eventfd_signal dalam keadaan kernel semasa mengundi lagi.
Memaklumkan keadaan kernel dari keadaan pengguna adalah sedikit lebih menyusahkan Pertama, anda perlu membuat eventfd dan kemudian menghantarnya ke file->private_data (operasi di sini adalah sama seperti di atas). iotcl dalam modul, yang bertanggungjawab untuk keadaan pengguna untuk memberitahu keadaan kernel , eventfd_signal dilakukan dalam fungsi Benang keadaan kernel perlu diletakkan pada eventfd_ctx->wqh terlebih dahulu dalam keadaan kernel sendiri (nampaknya menyusahkan lagi).

Artikel ini memperkenalkan eventfd, artifak dalam Linux Ia adalah mekanisme komunikasi antara proses yang mudah, fleksibel dan cekap. Kami menganalisis penciptaan, membaca dan menulis, dan membenderakan bit eventfd dari aspek prinsip, dan memberikan contoh kod yang sepadan. Kami juga memperkenalkan penggunaan eventfd dalam senario seperti mod pengguna dan komunikasi mod kernel, pemasa dan pencetus peristiwa dari perspektif aplikasi, dan memberikan contoh kod yang sepadan. Melalui kajian artikel ini, kita boleh menguasai penggunaan asas eventfd, dan boleh menggunakan eventfd secara fleksibel dalam pembangunan sebenar untuk mencapai keperluan komunikasi yang berbeza. Semoga artikel ini dapat membantu anda!

Atas ialah kandungan terperinci Artifak dalam Linux: Prinsip dan Aplikasi eventfd. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:lxlinux.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan