2011-04-20 33 views
3

我試圖端口實時Thread_Metric從ExpressLogic在POSIX,以基準PREEMPT_RT補丁的Linux,Xenomai RTAI和我的論文。他們提供了一個C源文件具有以下功能,你必須以實現對基準的工作:功能,這需要並行線程作爲輸入,並暫停其

void tm_initialize(void (*test_initialization_function)(void)); 
int tm_thread_create(int thread_id, int priority, void (*entry_function)(void)); 
int tm_thread_resume(int thread_id); 
int tm_thread_suspend(int thread_id); 
void tm_thread_relinquish(void); 
void tm_thread_sleep(int seconds); 
int tm_queue_create(int queue_id); 
int tm_queue_send(int queue_id, unsigned long *message_ptr); 
int tm_queue_receive(int queue_id, unsigned long *message_ptr); 
int tm_semaphore_create(int semaphore_id); 
int tm_semaphore_get(int semaphore_id); 
int tm_semaphore_put(int semaphore_id); 
int tm_memory_pool_create(int pool_id); 
int tm_memory_pool_allocate(int pool_id, unsigned char **memory_ptr); 
int tm_memory_pool_deallocate(int pool_id, unsigned char *memory_ptr); 

現在,我試圖執行tm_thread_suspend和tm_thread_resume功能,採取並行線程作爲輸入。我知道,你可以暫停與和的pthread_mutex_lock程序調用pthread_cond_wait一個並行線程,但你必須從線程start_function調用這些。我對這類東西很陌生,而且我的頭腦也很不自信。任何幫助表示讚賞。

回答

1

並行線程的一些實施方案具有這些功能。 http://www.unix.com/man-page/all/3t/pthread_suspend/但你的Linux內核可能不支持他們。

+0

'pthread_suspend'不是並行線程功能,它的一些供應商擴展。 – 2011-04-20 22:50:13

+0

'pthread_suspend()和pthread_continue()由X /開啓開發的。' – bmargulies 2011-04-21 01:18:17

+0

但尚未納入標準。你或許可以深入理解基本原理,找到一個很好的理由。 – 2011-04-21 01:21:50

3

pthread_suspend似乎真的去,如果它是可用的方式。這個解決方案可能比它的價值更骯髒。對於每個線程保持semaphore。讓每個線程監聽信號。在信號處理程序簡單地做相關的信號量down

所以,當你想stop一個線程,只需發送一個信號(也許使用實時信號將是最好的),它將停止在處理程序。處理程序默認屏蔽自己(也就是說,如果在完成之前接收到相同的信號,則不會再次調用它)。當你想重啓線程時,只需在信號量上做一個up

警告:

  • 使用提示,這是什麼@bmargulies更好(更安全,更清潔,更高效的),如果你能
  • 你也可以使用一個互斥鎖信號量
  • 處理的與信號是一個討厭的工作。在着手確保你(重新)瞭解
    • 異步信號安全
    • 線程和信號
    • 中斷並重新啓動系統調用(SA_RESTART
  • 我敢肯定sem_wait(3) ISN '異步信號安全,但它是安全的,只要你不使用SA_NODEFER(不是你有任何理由)

不幸的是,我找不到任何真正的恆星免費文檔。儘管如此,恆星還是沒有,還有很多免費的文檔。

編輯

至於建議由@R ..有async-signal-safe功能,阻止,你可以使用(而不是不安全sem_wait)。這裏是a list of functions you may safely use

+0

你有正確的方法,但需要在信號處理異步信號安全功能。我的答案勾勒出一些想法。 – 2011-04-20 22:57:00

+0

@R ..這是一個好主意。我可以看到'SUSv3'指定'PSELECT(2)'爲異步信號安全這將解決這種方法的問題。 – cnicutar 2011-04-21 04:10:22

1

你可以這樣做完全可移植性(避免與異步信號不安全函數的所有問題),使用兩個信號:

的「線程掛起」信號處理程序將使用pselect原子地疏通第二信號,並無限期地睡覺。第二個信號將終止pselect並導致信號處理程序返回。

也有大量使用異步信號安全接口,其他解決方案 - 基本上任何文件描述符交易和阻止他們,而不是在用戶空間的同步原語。例如,具有從管信號處理器read和寫入單個字節到管道恢復線程會工作。

0

你做到這一點的方法是,使用sigwait()和pthread_kill。

//全局變量

int _fSigSet; 

之前調用在pthread_create我們設置了信號屏蔽。每個線程都會繼承掩碼。你可以在我想的線程函數中設置掩碼。這裏是代碼,我們使用:

sigemptyset(&_fSigSet); 
sigaddset(&_fSigSet, SIGUSR1); 
sigaddset(&_fSigSet, SIGSEGV); 
pthread_sigmask(SIG_BLOCK, &_fSigSet, NULL); 
... 
pthread_create(&Thread, NULL, ThreadProc, NULL); 
... 

暫停:

int nSig; // signal you get if you care. 
sigwait(&_fSigSet, &nSig); // thread is suspended here waiting for signal. 

恢復:

pthread_kill(&Thread, SIGUSR1); 

如果您不能使用SIGUSR1出於某種原因要知道,不所有信號都適用於我們。我們可能做錯了,但SIGCONT不起作用。

我們已經暫停爲基準線這樣的,這種方法比使用互斥體和條件變量快5倍。

下面是一些code採用此方法。