[問題] volatile 在 Multithreading 中使用

看板C_and_CPP作者 (Thelink)時間12年前 (2013/06/12 06:04), 編輯推噓1(108)
留言9則, 6人參與, 最新討論串1/1
小弟寫了一個 pthread 的封裝 在判斷 thread 結束時 使用一個宣告為 volatile 變數來判斷是否要結束 thread 如以下表示 請問宣告成 volatile 變數 是不是在存取數值時就是 Atomic Operations. 不用 mutex 也可以 ? 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Linux GCC 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) pthread #ifndef WRAP_THREAD_H_ #define WRAP_THREAD_H_ #ifdef __cplusplus extern "C" { #endif typedef enum wrap_thread_status_t { WRAP_THREAD_STATUS_STOP = 0, WRAP_THREAD_STATUS_RUNNING = 1, } wrap_thread_status_t; typedef struct wrap_thread_t wrap_thread_t; typedef void (*wrap_thread_function)( wrap_thread_t *thread_device, void *thread_data ); wrap_thread_t* wrap_thread_initialize( wrap_thread_function thread_function, void *thread_data ); void wrap_thread_release( wrap_thread_t **device ); wrap_thread_status_t wrap_thread_status( wrap_thread_t *device ); #ifdef __cplusplus } #endif #endif /* WRAP_THREAD_H_ */ #include <stdlib.h> #include <pthread.h> #include "wrap_thread.h" struct wrap_thread_t { pthread_t handle; volatile wrap_thread_status_t status; void *thread_data; wrap_thread_function thread_function; }; static void *thread_start_routine( void *data ) { int result = 0; wrap_thread_t *device = (wrap_thread_t *) data; if ( device->thread_function == NULL ) { goto error_thread_function; } device->status = WRAP_THREAD_STATUS_RUNNING; while ( device->status ) { result = device->thread_function( device, device->thread_data ); if ( result != 0 ) { goto error_thread_function_result; } } error_thread_function_result : error_thread_function : return NULL ; } void wrap_thread_release( wrap_thread_t **device ) { if ( device == NULL ) { goto error_parameters; } if ( ( *device ) == NULL ) { goto error_parameters; } if ( ( *device )->handle != 0 ) { ( *device )->status = WRAP_THREAD_STATUS_STOP; pthread_join( ( *device )->handle, NULL ); ( *device )->handle = 0; } free( ( *device ) ); ( *device ) = NULL; error_parameters : return; } wrap_thread_t* wrap_thread_initialize( wrap_thread_function thread_function, void *thread_data ) { int result = 0; wrap_thread_t *device = NULL; if ( thread_function == NULL ) { goto error_parameters; } device = (wrap_thread_t *) malloc( sizeof( *device ) ); if ( device == NULL ) { goto error_new_device; } device->handle = NULL; device->thread_function = thread_function; device->thread_data = thread_data; device->status = WRAP_THREAD_STATUS_STOP; result = pthread_create( &device->handle, NULL, thread_start_routine, device ); if ( result != 0 ) { goto error_thread_create; } while ( device->status != WRAP_THREAD_STATUS_RUNNING ) { sched_yield( ); } return device; error_thread_create : wrap_thread_release( &device ); error_new_device : error_parameters : return device; } wrap_thread_status_t wrap_thread_status( wrap_thread_t *device ) { return device->status; } -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.134.201.106

06/12 14:30, , 1F
06/12 14:30, 1F

06/12 18:40, , 2F
06/12 18:40, 2F

06/12 20:27, , 3F
那篇寫得好好, 所以當讀取 status 還是要使用 mutex, 除非
06/12 20:27, 3F

06/12 20:29, , 4F
目前硬體平台有提供 atomaic 的操作 ?
06/12 20:29, 4F

06/12 22:12, , 5F
volatile只保證不會去cache取資料,不保證你程式寫得不好
06/12 22:12, 5F

06/12 22:13, , 6F
不會出現race condition,所以還是用mutex的好.
06/12 22:13, 6F

06/13 05:25, , 7F
可以使用c++11的atomic
06/13 05:25, 7F

07/06 22:07, , 8F
如果你是x86的機器你可以不用mutex,但這個跟volatile
07/06 22:07, 8F

07/06 22:07, , 9F
無關
07/06 22:07, 9F
文章代碼(AID): #1Hk0znc- (C_and_CPP)