boost::asio::thread_pool iterating over threads - boost

I have a quite nasty deadlock condition in my application which I know how to solve, but it requires me to get all thread ids in advance, after constructing the boost::asio::thread_pool, and before actually using it.
How can I iterate over all threads in a boost::asio::thread_pool in order to get the thread ids?

You can insert your threads into the pool:
#include <boost/asio.hpp>
#include <fmt/ranges.h>
#include <ranges>
#include <vector>
using std::ranges::views::transform;
static std::string pretty_id(std::thread::id id) {
return fmt::format("{:02x}", std::hash<std::thread::id>{}(id) % 0xff);
}
static std::string this_id() { return pretty_id(std::this_thread::get_id()); }
int main() {
boost::asio::thread_pool pool(0); // empty
std::vector<std::thread::id> ids;
for (int i = 0; i<10; ++i) {
std::thread worker{[&pool] {
fmt::print("Thread {} attaching\n", this_id());
pool.attach();
fmt::print("Thread {} exiting\n", this_id());
}};
ids.push_back(worker.get_id());
worker.detach(); // attach transfers ownership to pool
}
fmt::print("Operational: {}\n", ids | transform(pretty_id));
pool.join();
}
See it Live On Coliru, printing
Thread fa attaching
Thread d3 attaching
Thread 82 attaching
Thread a3 attaching
Thread 31 attaching
Thread 35 attaching
Thread 32 attaching
Thread e5 attaching
Thread f0 attaching
Operational: ["fa", "d3", "a3", "31", "82", "35", "32", "e5", "f0", "d6"]
Thread d6 attaching
Thread d6 exiting
Thread fa exiting
Thread d3 exiting
Thread 82 exiting
Thread a3 exiting
Thread e5 exiting
Thread 31 exiting
Thread f0 exiting
Thread 32 exiting
Thread 35 exiting
CAVEAT: the idea of "fixing" deadlocks with bespoke logic based on thread ids sounds like a design smell.

Related

C++ Async function not launched asynchronously

I am trying to launch a function asynchronously but it gets launched synchronously.
#include <thread>
#include <future>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
std::future<int> setPromise()
{
auto promise = std::make_shared<std::promise<int>>();
auto future = promise->get_future();
auto asyncFn = [&]() {
cout << "Async started ...\n";
for(int i=0; i<100000; i++)
for(int j=0; j<10000; j++) {}
promise->set_value(400);
fprintf(stderr, "Async ended ...\n");
};
std::async(std::launch::async, asyncFn);
return future;
}
int main()
{
std::future<int> result = setPromise();
cout << "Asynchronously launched \n";
int ret = result.get();
cout << ret << endl;
return 0;
}
Compiled it with the following command
g++ -std=c++11 -pthread promise.cpp -o promise
I expect the lambda function to get called asynchronously and while the loop is running in asynchronous thread i expect the logs from the main. But i see the function never gets launched asynchronously and always the lambda gets completed and only then we get the next statements in main to be executed
What i expect
Async started ...
Asynchronously launched
Async ended ...
What i get is
Async started ...
Async ended ...
Asynchronously launched
By calling below line
std::async(std::launch::async, asyncFn);
is created temporary future object, and its destructor ends only if task started by async finishes. So at the end of scope of setPromise function its execution is blocked until job - asyncFn ends.
You can read about behaviour future destrcutor here and what happens when shared state of future is not ready.
It probably is running asynchronously just completes quickly.
To confirm for sure, you need to make your logging race condition free.
Something like this (just the idea):
std::future<int> setPromise()
{
std::atomic_flag canGo = ATOMIC_FLAG_INIT;
auto asyncFn = [&] {
while (!canGo);
log("Async started ..."); // also use thread-safe logging
...
}
std::async(std::launch::async, asyncFn);
log("letting it go...");
canGo.test_and_set();
...
}
Note also, that iostream is not thread safe, so you better use a thread safe logger when experimenting.

Fifo Flushing Error

I am trying this code,
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<signal.h>
int fileFD = 0;
pthread_t Thread_application;
pthread_t Read_Thread;
void * Waiting_Thread(void * arg)
{
while(1) {
printf("Created Thread\n");
sleep(1);
}
}
void * Readtread(void *arg)
{
char buf[1902] = {0};
int ret = 0;
while(1) {
ret = read(fileFD, buf, 120);
printf("Read Bytes\n");
}
}
void main()
{
int i = 0;
mkfifo("Desktop/Trail_Programs/ClientFIFO", 0666);
fileFD = open("Desktop/Trail_Programs/ClientFIFO", O_RDWR);
pthread_create(&Thread_application, NULL, Waiting_Thread, NULL);
pthread_create(&Read_Thread, NULL, Readtread, NULL);
sleep(10);
close(fileFD);
pthread_kill(Thread_application, 0);
pthread_kill(Read_Thread, 0);
system("dd if=Desktop/Trail_Programs/ClientFIFO iflag=nonblock of=/dev/null");
for(i = 0; i < 10; i++) {
printf("Main Thread \n");
fflush(stdout);
}
}
Output: Created Thread
Created Thread
Created Thread
Created Thread
Created Thread
Created Thread
Created Thread
Created Thread
Created Thread
Created Thread
Created Thread
dd: error reading
‘Desktop/Trail_Programs/ClientFIFO’: Resource
temporarily unavailable
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000314463 s, 0.0 kB/s
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
I suppose read is blocking while i am trying to flush the fifo into /dev/null. In my use case opening file with O_NONBLOCK flag and using select to monitor fd, keeps my other processes lagging. please help me with some suggestions
Thanks and Regards,
Ap

OpenThread returns same handle for different threads ID

Using the following code taken from here with some additions to get thread handles, OpenThread returns the same handle but different ID for each thread in a process.
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
int __cdecl main(int argc, char **argv)
{
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
HANDLE hThread;
if (h != INVALID_HANDLE_VALUE) {
THREADENTRY32 te;
te.dwSize = sizeof(te);
if (Thread32First(h, &te)) {
do {
if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +
sizeof(te.th32OwnerProcessID)) {
hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, te.th32ThreadID);
printf("Process 0x%04x Thread 0x%04x Handle %d\n",
te.th32OwnerProcessID, te.th32ThreadID, hThread);
CloseHandle(hThread);
}
te.dwSize = sizeof(te);
} while (Thread32Next(h, &te));
}
CloseHandle(h);
}
return 0;
}
Some output:
Process 0x10fc Thread 0x2270 Handle 68
Process 0x10fc Thread 0x13d4 Handle 68
Process 0x10fc Thread 0x071c Handle 68
Process 0x10fc Thread 0x2140 Handle 68
Process 0x10fc Thread 0x20d4 Handle 68
Process 0x1b70 Thread 0x21e8 Handle 68
Process 0x1c7c Thread 0x1d18 Handle 68
Process 0x1c7c Thread 0x10b8 Handle 68
Process 0x0d84 Thread 0x1fa0 Handle 68
So how am I supposed to use functions which needs a thread handle if all of them have the same number?
If you need to keep a handle to the thread, don't close the handle!

Creating Thread in Win32

Does ThreadFunc() gets called two times here? sometimes I notice a single call and sometimes none at all.
#include <windows.h>
#include <stdio.h>
DWORD WINAPI ThreadFunc(LPVOID);
int main()
{
HANDLE hThread;
DWORD threadld;
hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, &threadld );
printf("Thread is running\n");
}
DWORD WINAPI ThreadFunc(LPVOID p)
{
printf("In ThreadFunc\n");
return 0;
}
Output 1
Thread is running
In ThreadFunc
In ThreadFunc
Press any key to continue . . .
Output 2
Thread is running
In ThreadFunc
Press any key to continue . . .
Output 3
Thread is running
Press any key to continue . . .
In order to call CRT functions, such as printf you should use _beginthread or _beginthreadex instead of CreateThread.
Anyway, the program may end before the thread has the opportunity to output anything.
A little addition: use WaitForSingleObject inside main() to give your thread finish a job.
No, ThreadFunc should never get called twice. In any case, I believe your code snippet is incomplete - could you post the full code snippet where you are seeing this problem?

Pthreads in Mac OS X - Mutexes issue

I'm trying to learn how to program parallel algorithms in C using POSIX threads. My environment is a Mac OS X 10.5.5 with gcc 4.
Compiling:
gcc -Wall -D_REENTRANT -lpthread source.c -o test.o
So, my problem is, if I compile this in a Ubuntu 9.04 box, it runs smoothly in thread order, on Mac looks like mutexes doesn't work and the threads don't wait to get the shared information.
Mac:
#1
#0
#2
#5
#3
#4
ubuntu
#0
#1
#2
#3
#4
#5
Any ideas?
Follow below the source code:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define NUM_THREADS 6
pthread_mutex_t mutexsum;
pthread_t threads[NUM_THREADS];
long Sum;
void *SumThreads(void *threadid){
int tmp;
int i,x[10],y[10];
// Para cada x e y do vetor, jogamos o valor de i, só para meio didáticos
for (i=0; i<10 ; i++){
x[i] = i;
y[i] = i;
}
tmp = Sum;
for (i=0; i<10 ; i++){
tmp += (x[i] * y[i]);
}
pthread_mutex_lock (&mutexsum);
Sum += tmp;
printf("Im thread #%ld sum until now is: %ld\n",threadid,Sum);
pthread_mutex_unlock (&mutexsum);
return 0;
}
int main(int argc, char *argv[]){
int i;
Sum = 0;
pthread_mutex_init(&mutexsum, NULL);
for(i=0; i<NUM_THREADS; i++){
pthread_create(&threads[i], NULL, SumThreads, (void *)i);
}
pthread_exit(NULL);
}
There is nothing on your code that will make your threads running in ANY order. If in Ubuntu is running on some order, it might be because you are just lucky. Try running 1000 times in Ubuntu and see if you get the same results over and over again.
The thing is, that you can't control the way the scheduler will make your threads access the processor(s). So, when you iterate through the for loop is creating your threads, you can't assume that the first call to pthread_create will get to run first, or will get to lock the mutex you are creating first. It's up to the scheduler which it at the OS level, and you can't control it, unless you write your own kernel :-).
If you want a serial behavior why would you run your code in separate threads in the first place? If it is just for experimentation, then one solution I can think of using pthread_signal to wake a specific thread up and make it running... Then the woken up thread can wake up the second one and so on so forth.
Hope it helps.
To my recollection, the variable you have protected isn't actually being shared amongst the processes. It exists in its own context inside each of the threads. So, it's really just a matter of when each thread gets scheduled that determines what will print.
I don't think one simple mutex will allow you to guarantee correctness, if correctness is defined as printing 0, 1, 2, 3 ...
what your code is doing is creating multiple execution contexts, using the code in your sum function as its execution code. the variable you are protecting, unless declared as static, will be unique to each call of that function.
in the end, it is coincidence that you are getting one system to print out correctly, because you have no logical method of blocking threads until it is their proper turn.
I don't do pthreads in C or any other language (but I do thread programming on high-performace computers) so this 'answer' might be useless to you;
What in your code requires the threads to pass the mutex in thread id order ? I see that the threads are created in id order, but what requires them to execute in that order /
If you do require your threads to execute in id order, why ? It seems a bit as if you are creating threads, then serialising them. To what end ?
When I program in threads and worry about execution order, I often try creating a very large number of threads and seeing what happens to the execution order.
As I say, ignore this if my lack of understanding of C and pthreads is too poor.

Resources