<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/zig-s-io-threaded-is-neat-asnt4devz" -->

---
title: Zig’s Io.Threaded is Neat | daily.dev
description: Zig&#x27;s std.Io.Threaded is a concurrency implementation that uses blocking syscalls while fully supporting cancellation. The post explains why cancellation is...
canonical: https://daily.dev/posts/zig-s-io-threaded-is-neat-asnt4devz
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Zig’s Io.Threaded is Neat | daily.dev
og:description: Zig&#x27;s std.Io.Threaded is a concurrency implementation that uses blocking syscalls while fully supporting cancellation. The post explains why cancellation is...
og:url: https://daily.dev/posts/zig-s-io-threaded-is-neat-asnt4devz
og:image: https://api.daily.dev/og/posts/asNT4dEvz.png
og:image:alt: Zig’s Io.Threaded is Neat
og:image:width: 1200
og:image:height: 630
og:locale: en
---

[matklad](https://daily.dev/sources/matklad)

[Read post](https://api.daily.dev/r/asNT4dEvz)

# [Zig’s Io.Threaded is Neat](https://api.daily.dev/r/asNT4dEvz "Go to post")

Zig's std.Io.Threaded is a concurrency implementation that uses blocking syscalls while fully supporting cancellation. The post explains why cancellation is fundamental to concurrency (not just a nice-to-have), then details how Io.Threaded achieves it on POSIX using a signal+flag protocol: a canceling thread sets a shared-memory flag and repeatedly sends a signal to interrupt the blocked syscall via EINTR, which the cancellee checks before retrying or acknowledging. On Windows, the more direct NtCancelSynchronousIoFile is used. The post contrasts this with Java's thread interruption (which doesn't reach syscalls) and pthread\_cancel (which lacks language-level integration and tears down the whole thread). Zig's Io interface also cleanly separates 'may run concurrently' (io.async, infallible) from 'must run concurrently' (io.concurrent, fallible), backed by a thread pool with fresh-thread fallback.

[#zig](/tags/zig "Check all #zig posts")

Aug 06•5m read time•From [matklad.github.io](https://api.daily.dev/r/asNT4dEvz "matklad.github.io")

[![Post cover image](https://media.daily.dev/image/upload/s--OHB84bZF--/f_auto/v1722860399/public/Placeholder%2010)](https://api.daily.dev/r/asNT4dEvz "Go to post")

Table of contents

[Concurrency vs Parallelism](https://api.daily.dev/r/asNT4dEvz "Concurrency vs Parallelism")[Just Use Threads](https://api.daily.dev/r/asNT4dEvz "Just Use Threads")[SIGIO](https://api.daily.dev/r/asNT4dEvz "SIGIO")[Prior Art](https://api.daily.dev/r/asNT4dEvz "Prior Art")

Questions this post answers

How does Zig's std.Io.Threaded cancel a thread blocked inside a blocking syscall?

Io.Threaded uses a POSIX signal-plus-flag protocol. The canceling thread sets a flag in shared memory, then repeatedly signals the target thread until cancellation is acknowledged. The signal causes the blocked syscall to return EINTR; the cancellee checks the shared flag and either retries the syscall or acknowledges cancellation and begins unwinding. On Windows, the more direct NtCancelSynchronousIoFile API is used instead. Developers working with Zig concurrency track Io interface changes like these on daily.dev.

What is the difference between io.async and io.concurrent in Zig's Io interface?

io.async means a task 'may run concurrently' and is infallible — it never fails to schedule. io.concurrent means a task 'must run concurrently' and is always fallible, because spawning a thread can fail. Concurrent tasks are backed by a thread pool, falling back to spawning a fresh thread only when the pool is exhausted. This separation makes signatures more precise and intent clearer. Systems developers choosing between Zig concurrency primitives find the latest Zig ecosystem discussions on daily.dev.

Why doesn't pthread\_cancel work well as a language-level cancellation mechanism?

pthread\_cancel lacks integration with language-level constructs like try and defer, making post-cancellation cleanup cumbersome. It also tears down the entire thread, which is costly because thread creation is slow and OS thread limits are typically low. Pooling threads is therefore preferable, but pthread\_cancel's whole-thread teardown makes that impractical. Engineers evaluating threading models for systems software follow these trade-off discussions on daily.dev.

20.4K Impressions14 Upvotes1 Comment

Comment

Bookmark

Copy

![Placeholder image for anonymous user](https://media.daily.dev/image/upload/s--qsFuKGv_--/t_logo,f_auto/public/noProfile)Share your thoughtsPost

[![matklad's image](https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/c34dbbf360354a179786e8a127718b12)](https://daily.dev/sources/matklad)

[matklad](https://daily.dev/sources/matklad "https://daily.dev/sources/matklad")

Matthias Noback's expertise in PHP and domain-driven design (DDD) offers readers insights into buil... Read more

33 Followers

•

474 Upvotes

#### Would you recommend this post?

Copy link

WhatsApp

Facebook

X

New Squad

Copy linkShare with your friends

14

1

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Zig’s Io.Threaded is Neat","url":"https://daily.dev/posts/zig-s-io-threaded-is-neat-asnt4devz","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/zig-s-io-threaded-is-neat-asnt4devz"},"datePublished":"2026-08-06T15:34:09.589Z","dateModified":"2026-08-06T15:34:38.747Z","description":"Zig's std.Io.Threaded is a concurrency implementation that uses blocking syscalls while fully supporting cancellation. The post explains why cancellation is...","image":"https://media.daily.dev/image/upload/s--OHB84bZF--/f_auto/v1722860399/public/Placeholder%2010","thumbnailUrl":"https://media.daily.dev/image/upload/s--OHB84bZF--/f_auto/v1722860399/public/Placeholder%2010","isAccessibleForFree":true,"articleSection":"matklad","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"matklad","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/c34dbbf360354a179786e8a127718b12","url":"https://daily.dev/sources/matklad"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/zig-s-io-threaded-is-neat-asnt4devz","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":14},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"zig","timeRequired":"PT5M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"matklad","item":"https://daily.dev/sources/matklad"},{"@type":"ListItem","position":3,"name":"Zig’s Io.Threaded is Neat"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/zig-s-io-threaded-is-neat-asnt4devz","comment":[{"@type":"Comment","text":"I’d test cancellation on both sides of every syscall boundary, especially around that signal-and-flag handshake.","datePublished":"2026-08-11T02:45:25.330Z","url":"https://daily.dev/posts/asNT4dEvz#c-FHo35Lxky","author":{"@type":"Person","name":"Agustin Barrientos","url":"https://daily.dev/agustinbarrientos","image":"https://media.daily.dev/image/upload/s--5ayxQnqn--/f_auto/v1783272917/avatars/avatar_wQYYVe5Tbj0NJ7C7qPoa8?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/zig-s-io-threaded-is-neat-asnt4devz#faq","mainEntity":[{"@type":"Question","name":"How does Zig's std.Io.Threaded cancel a thread blocked inside a blocking syscall?","acceptedAnswer":{"@type":"Answer","text":"Io.Threaded uses a POSIX signal-plus-flag protocol. The canceling thread sets a flag in shared memory, then repeatedly signals the target thread until cancellation is acknowledged. The signal causes the blocked syscall to return EINTR; the cancellee checks the shared flag and either retries the syscall or acknowledges cancellation and begins unwinding. On Windows, the more direct NtCancelSynchronousIoFile API is used instead. Developers working with Zig concurrency track Io interface changes like these on daily.dev."}},{"@type":"Question","name":"What is the difference between io.async and io.concurrent in Zig's Io interface?","acceptedAnswer":{"@type":"Answer","text":"io.async means a task 'may run concurrently' and is infallible — it never fails to schedule. io.concurrent means a task 'must run concurrently' and is always fallible, because spawning a thread can fail. Concurrent tasks are backed by a thread pool, falling back to spawning a fresh thread only when the pool is exhausted. This separation makes signatures more precise and intent clearer. Systems developers choosing between Zig concurrency primitives find the latest Zig ecosystem discussions on daily.dev."}},{"@type":"Question","name":"Why doesn't pthread_cancel work well as a language-level cancellation mechanism?","acceptedAnswer":{"@type":"Answer","text":"pthread_cancel lacks integration with language-level constructs like try and defer, making post-cancellation cleanup cumbersome. It also tears down the entire thread, which is costly because thread creation is slow and OS thread limits are typically low. Pooling threads is therefore preferable, but pthread_cancel's whole-thread teardown makes that impractical. Engineers evaluating threading models for systems software follow these trade-off discussions on daily.dev."}}]}
```

