Skip to content

refactor(samples): replace pthreads with std::thread in multithreaded sample #13733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a569a97
chore: remove Visual Studio-related files for cross-platform cleanup
Subham-KRLX Jun 15, 2025
62189d5
chore: remove build.cmd reference from tasks.json
Subham-KRLX Jun 16, 2025
b32e26d
Merge branch 'main' into cleanup/remove-vs-files
Subham-KRLX Jun 19, 2025
3310fe1
Merge branch 'main' into cleanup/remove-vs-files
Subham-KRLX Jun 25, 2025
d7b9c2c
chore(samples): port Fib sample to std::thread, improve thread safety…
Subham-KRLX Jun 27, 2025
f75761b
chore: remove launch.json from PR (not part of extension)
Subham-KRLX Jun 27, 2025
7005da9
Complete pthread to std::thread migration:
Subham-KRLX Jun 28, 2025
099970d
refactor(samples): migrate to std::thread and add tasks.json for Fib …
Subham-KRLX Jul 1, 2025
c7eef6c
chore: update Extension tasks.json
Subham-KRLX Jul 1, 2025
3b47e67
chore: remove unrelated changes to Extension/.vscode/tasks.json
Subham-KRLX Jul 2, 2025
9c4796e
chore: update Extension/.vscode/tasks.json to restore correct build t…
Subham-KRLX Jul 2, 2025
7b08175
refactor(samples): complete pthread to std::thread migration
Subham-KRLX Jul 3, 2025
1acd5a4
Merge branch 'main' into feature/cpp11-thread-sample
Subham-KRLX Jul 3, 2025
d9335fa
Fix issue with lost edits in config UI (#13746)
Colengms Jul 7, 2025
7f835f0
Finalize multithreaded sample with cross-platform support:
Subham-KRLX Jul 8, 2025
eab01ac
Merge branch 'main' into feature/cpp11-thread-sample
Subham-KRLX Jul 8, 2025
c9b5be7
Merge branch 'main' into feature/cpp11-thread-sample
Subham-KRLX Jul 11, 2025
016ce5e
Merge branch 'main' into feature/cpp11-thread-sample
Subham-KRLX Jul 17, 2025
90ce521
Fix remaining issues based on reviewer feedback (e.g., tasks.json, la…
Subham-KRLX Jul 17, 2025
a6f8056
Merge branch 'main' into feature/cpp11-thread-sample
Subham-KRLX Jul 24, 2025
de11942
Merge branch 'main' into feature/cpp11-thread-sample
Subham-KRLX Jul 30, 2025
5450c49
Merge branch 'main' into feature/cpp11-thread-sample
Subham-KRLX Aug 2, 2025
07478e2
Restore build.cmd for Windows builds
Subham-KRLX Aug 2, 2025
2441261
Update Windows build task to use build.cmd
Subham-KRLX Aug 2, 2025
d74bfea
Merge branch 'main' into feature/cpp11-thread-sample
Subham-KRLX Aug 6, 2025
2bae38b
Merge branch 'main' into feature/cpp11-thread-sample
sean-mcmanus Aug 7, 2025
64f84a7
Update build.cmd
Subham-KRLX Aug 8, 2025
c6df027
Update tasks.json
Subham-KRLX Aug 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 0 additions & 40 deletions Code Samples/Fib/.vscode/launch.json

This file was deleted.

87 changes: 39 additions & 48 deletions Code Samples/Fib/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"windows": {
"command": "${workspaceRoot}/build.cmd",
"args": [
"<Path/To/MinGW/Cygwin/Bin/Folder>", // Path to the bin folder containing g++ to compile
"fib.exe" // Output executable name
]
},
"linux": {
"command": "g++",
"args": [
"-g",
"*.cpp",
"-lpthread",
"--std=c++11",
"-o",
"fib.out"
]
},
"osx": {
"command": "g++",
"args": [
"-g",
"*.cpp",
"-lpthread",
"--std=c++11",
"-o",
"fib.out"
]
}
}
]
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"linux": {
"command": "g++",
"args": [
"-g",
"*.cpp",
"-lpthread",
"--std=c++11",
"-o",
"fib.out"
]
},
"osx": {
"command": "g++",
"args": [
"-g",
"*.cpp",
"-lpthread",
"--std=c++11",
"-o",
"fib.out"
]
}
}
]
}
18 changes: 18 additions & 0 deletions Code Samples/Fib/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CXX := g++
CXXFLAGS := -std=c++11 -Wall -Wextra -pthread
LDFLAGS := -pthread

SRCS := main.cpp thread.cpp
OBJS := $(SRCS:.cpp=.o)
TARGET := fib_sample

all: $(TARGET)

$(TARGET): $(OBJS)
$(CXX) $(OBJS) -o $@ $(LDFLAGS)

%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@

clean:
rm -f $(OBJS) $(TARGET)
2 changes: 0 additions & 2 deletions Code Samples/Fib/build.cmd

This file was deleted.

111 changes: 72 additions & 39 deletions Code Samples/Fib/main.cpp
Original file line number Diff line number Diff line change
@@ -1,58 +1,91 @@
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#include <thread>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <atomic>
#include <chrono>
#include <csignal>
#include <unistd.h> // Required for getpid()
#include "thread.h"

#define THREAD_COUNT 10

static char block[] = "--block";
int test = 0;
static constexpr char block[] = "--block";
static constexpr char crash[] = "--crash";
static constexpr char test_flag[] = "--test";
std::atomic<int> test_count{0}; // Thread-safe counter
volatile std::sig_atomic_t g_signal_status = 0;

void signal_handler(int signal) {
g_signal_status = signal;
}

int main(int argc, char **argv)
{
srand(time(NULL));
// Register signal handler for clean interruption
std::signal(SIGINT, signal_handler);

static char pidText[] = "PID: ";
std::string helpText = "Attach a debugger and execute 'set foo=0' to continue";
char helloText[] = "Hello World!";
// Initialize random seed
std::srand(static_cast<unsigned>(std::time(nullptr)));

std::cout << helloText << std::endl;
std::cout << "Hello World!" << std::endl;

pthread_t threads[THREAD_COUNT];
if (argc == 2) {
if (std::strcmp(block, argv[1]) == 0) {
std::cout << "Attach a debugger and set foo=0 to continue" << std::endl;
std::cout << "Process ID: " << getpid() << std::endl;

if (argc == 2 && !strcmp(block, argv[1]))
{
std::cout << helpText << std::endl;
volatile int foo = 1;
while (foo)
;
volatile int foo = 1;
while (foo && g_signal_status == 0) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Waiting... (press Ctrl-C to quit)" << std::endl;
}
return 0;
}
else if (std::strcmp(crash, argv[1]) == 0) {
std::cout << "Triggering intentional crash..." << std::endl;
volatile int foo = 0;
volatile int bar = 1 / foo; // Guaranteed crash
(void)bar; // Suppress unused-variable warning
return 1; // Unreachable after crash
}
else if (std::strcmp(test_flag, argv[1]) == 0) {
std::cout << "Running in test mode" << std::endl;
// Add any test-specific code here
}
}

if (argc == 2 && !strcmp("--crash", argv[1]))
{
int foo = 0;
int bar = 1 / foo;
}
// Thread management
std::vector<std::thread> threads;
threads.reserve(THREAD_COUNT);

for (int i = 0; i < THREAD_COUNT; i++)
{
std::cout << "Test " << i << std::endl;
pthread_create(&threads[i], NULL, &thread_proc, NULL);
}
try {
// Create and launch threads
for (int i = 0; i < THREAD_COUNT; ++i) {
std::cout << "Launching thread " << i << std::endl;
threads.emplace_back(thread_proc);
}

for (int i = 0; i < THREAD_COUNT; i++)
{
pthread_join(threads[i], NULL);
test++;
// Join all threads
for (auto& t : threads) {
if (t.joinable()) {
t.join();
test_count.fetch_add(1, std::memory_order_relaxed);
}
}
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
for (auto& t : threads) {
if (t.joinable()) {
t.detach();
}
}
return 1;
}

std::cout << "All threads exited!" << std::endl;

return 1;
std::cout << "\nAll " << test_count.load() << " threads completed successfully!" << std::endl;
return 0;
}
74 changes: 40 additions & 34 deletions Code Samples/Fib/thread.cpp
Original file line number Diff line number Diff line change
@@ -1,48 +1,54 @@
#include "thread.h"
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <thread>
#include <chrono>
#include <atomic>
#include <string>
#include <random>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#include "thread.h"

static int g_tid = 0;
// Thread-safe counter for thread IDs
static std::atomic<int> g_tid{0};

static int fib(int n){
// Generate fibonacci numbers recursively
static int fib(int n) {
switch (n) {
case 0: return 1;
case 1: return 1;
default: return (fib(n-2) + fib(n-1));
default: return fib(n - 1) + fib(n - 2);
}
}

void * thread_proc(void* ctx)
{
int tid = g_tid++;

char thread_name[16];
sprintf(thread_name, "Thread %d", tid);
#ifdef __APPLE__
pthread_setname_np(thread_name);
#else
pthread_setname_np(pthread_self(), thread_name);
// Set thread name (platform-specific) with Linux truncation
static void set_thread_name(const std::string& name) {
#if defined(__APPLE__)
pthread_setname_np(name.c_str());
#elif defined(__linux__)
std::string n = name.substr(0, 15); // limit ≤15 chars plus null (Linux limit) :contentReference[oaicite:0]{index=0}
pthread_setname_np(pthread_self(), n.c_str());
#endif
}

// Thread-local RNG for good random delays
static thread_local std::mt19937_64 rng{std::random_device{}()};

// Random delay, 0 - 0.5 sec
timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 500000000 + ((float)rand() / (float)RAND_MAX) * 500000000;
nanosleep(&ts, NULL);

volatile int i = 0;
while (i <= 30) {
std::cout << "Thread " << tid << ": fib(" << i << ") = " << fib(i) << std::endl;
i++;
nanosleep(&ts, NULL);
// Uniform integer generator
static int intRand(int min, int max) {
return std::uniform_int_distribution<int>(min, max)(rng);
}

void thread_proc() {
int tid = g_tid.fetch_add(1, std::memory_order_relaxed);
std::string thread_name = "Thread " + std::to_string(tid);
set_thread_name(thread_name);

auto delay = std::chrono::nanoseconds(500000000 + intRand(0, 500000000));

std::this_thread::sleep_for(delay);
for (int i = 0; i <= 30; ++i) {
std::cout << thread_name << ": fib(" << i << ") = " << fib(i) << "\n";
std::this_thread::sleep_for(delay);
}

std::cout << thread_name << " exited!" << std::endl;
}
std::cout << thread_name << " exited!\n";
}
9 changes: 8 additions & 1 deletion Code Samples/Fib/thread.h
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
void * thread_proc(void* ctx);
#pragma once

/**
* @brief Launches a background thread computing Fibonacci numbers with random delays.
*/
void thread_proc();