C++跨平台(Linux/Windows)线程通信、定时及字符获取问题求助
Hey there! Let's tackle your C++ pthread issues step by step, while making sure your code works smoothly across both Linux and Windows. I'll cover each of your questions and provide a revised code example to tie it all together.
To make a thread re-run at fixed intervals, wrap your task logic in a loop and add a delay between iterations. Here are your practical options:
- Simple delays: Use
sleep()(Linux, seconds) orSleep()(Windows, milliseconds) for basic timing. For finer-grained control, usenanosleep()(Linux) orSleepEx()(Windows). - Cancellable timed waits: If you need to stop the thread gracefully, pair a condition variable with
pthread_cond_timedwait()(Linux) instead of raw sleep—this lets you wake the thread early if needed.
Example for a periodic thread (Linux-focused, with cross-platform hints):
bool should_stop = false; // Shared flag to control the thread void *PeriodicTask(void *arg) { while (!should_stop) { // Your core task logic here cout << "Running periodic task..." << endl; // Wait 5 seconds before next run #ifdef __linux__ sleep(5); #elif _WIN32 Sleep(5000); // Windows uses millisecond values #endif } pthread_exit(NULL); }
Your current cin >> TT only reads until the first whitespace. To capture full lines including spaces, use getline() instead. Also, note that cin >> leaves a leftover newline in the input buffer, which will cause getline() to read an empty line—fix this with cin.ignore().
Additionally, cout/cin aren't thread-safe by default, so wrap input/output operations in a mutex to avoid garbled text:
pthread_mutex_t io_mutex; // Declare this globally or pass as an argument void *Saisie(void *PT) { string TT; // Use std::string instead of char arrays for safety pthread_mutex_lock(&io_mutex); cout << "Entrez une chaîne de caractères :" << endl; cin.ignore(); // Clear the leftover newline from the input buffer getline(cin, TT); pthread_mutex_unlock(&io_mutex); // Update shared state safely (always use a mutex!) pthread_mutex_lock(&io_mutex); t = true; pthread_mutex_unlock(&io_mutex); pthread_exit(NULL); }
Here are the most reliable ways to coordinate between threads in C++ (cross-platform where possible):
- Shared variables + mutexes: Protect any shared data (like your
tboolean) withpthread_mutex_t(Linux) orCRITICAL_SECTION(Windows) to prevent race conditions. - Condition variables: Pair a mutex with
pthread_cond_t(Linux) orCONDITION_VARIABLE(Windows) to signal threads when a specific condition is met (e.g., "new input is ready"). - Semaphores: Use
sem_t(Linux) orCreateSemaphore()(Windows) to control access to limited resources or signal events between threads. - Thread-safe queues: Implement a custom queue with mutexes/condition variables for structured message passing between threads.
WaitForSingleObject() WaitForSingleObject() is a Windows API that waits for a kernel object (thread, event, mutex, etc.) to be signaled. Here's what to use on Linux:
- Wait for a thread to finish: Use
pthread_join(), which blocks until the target thread exits. - Wait for an event: Simulate Windows events with a condition variable + mutex. For a lightweight Linux-specific alternative, use
eventfd(). - Wait for a mutex:
pthread_mutex_lock()blocks until the mutex is available. - Timed waits: Use
pthread_cond_timedwait()(for condition variables) orsem_timedwait()(for semaphores) to wait with a timeout, mirroringWaitForSingleObject()'s timeout behavior.
Here's a polished version of your code that addresses all your issues, with thread communication and periodic execution included:
#include <iostream> #include <cstdlib> #include <string> #include <pthread.h> #include <unistd.h> // For sleep() on Linux using namespace std; bool should_stop = false; bool input_received = false; pthread_mutex_t mutex; pthread_cond_t cond; string input_str; #define NUM_THREADS 2 void *Saisie(void *arg) { pthread_mutex_lock(&mutex); cout << "Entrez une chaîne de caractères :" << endl; cin.ignore(); getline(cin, input_str); input_received = true; pthread_cond_signal(&cond); // Signal main thread input is ready pthread_mutex_unlock(&mutex); pthread_exit(NULL); } void *PeriodicTask(void *arg) { while (!should_stop) { pthread_mutex_lock(&mutex); cout << "Periodic task running..." << endl; pthread_mutex_unlock(&mutex); sleep(3); // Wait 3 seconds before next run } pthread_exit(NULL); } int main() { pthread_t threads[NUM_THREADS]; int rc; // Initialize synchronization primitives pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); // Create input thread rc = pthread_create(&threads[0], NULL, Saisie, NULL); if (rc) { cerr << "Error creating input thread: " << rc << endl; exit(-1); } // Create periodic task thread rc = pthread_create(&threads[1], NULL, PeriodicTask, NULL); if (rc) { cerr << "Error creating periodic thread: " << rc << endl; exit(-1); } // Wait for input to be received pthread_mutex_lock(&mutex); while (!input_received) { pthread_cond_wait(&cond, &mutex); } cout << "Received input: " << input_str << endl; pthread_mutex_unlock(&mutex); // Stop periodic thread and clean up should_stop = true; for (int i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); return 0; }
For full Windows compatibility, replace pthread calls with Windows API equivalents (e.g., CreateThread, InitializeCriticalSection) and wrap platform-specific code in #ifdef _WIN32 directives.
内容的提问来源于stack exchange,提问作者Gregoire Rouet

