日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux多线程时序问题,Linux时序竞态问题(sleep函数的实现)

發布時間:2024/7/19 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux多线程时序问题,Linux时序竞态问题(sleep函数的实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

時序競態是指同樣的程序,多次調用運行的結果不同,這是由于爭奪系統資源所造成的。比如說我們要使用alarm和pause函數來實現一個sleep的功能,那么由于alarm函數的實現過程并不是一個原子操作,那么隨時可能被中斷。比如說alarm了1秒,在這個過程中,進程失去了CPU,然后當該進程再次獲得CPU的時候可能這個時間已經大于1秒了,那么對于alarm來說就已經發出了SIGALRM信號。此時往下繼續調用pause函數的話,它會一直都收不到alarm發來的信號,所以導致進程的永久掛起。

為了解決這個問題,引用了sigsuspend函數。sigsuspend用于在接收到某個信號之前,臨時用mask替換進程的信號掩碼,并暫停進程執行,直到收到信號為止。也就是說,進程執行到sigsuspend時,sigsuspend并不會立刻返回,進程處于TASK_INTERRUPTIBLE狀態并立刻放棄CPU,等待UNBLOCK(mask之外的)信號的喚醒。進程在接收到UNBLOCK(mask之外)信號后,調用處理函數,然后還原信號集,sigsuspend返回,進程恢復執行。下面通過使用alarm和sigsuspend函數來實現sleep函數,代碼中有詳細的注釋來解釋說明:

#include

#include

#include

#include

#include

#include

void sig_alarm(int num){ // 空函數僅用來捕捉信號

}

unsigned int mysleep(unsigned int n_seconds){

struct sigaction n_sig, o_sig; // 一個用來設定,一個用來備份

sigset_t nsigmask, osigmask, tmpsigmask; // 用來設定,備份,替換

/*初始化*/

n_sig.sa_handler = sig_alarm; // 設定信號的捕捉動作

n_sig.sa_flags = 0;

sigemptyset(&n_sig.sa_mask);

sigaction(SIGALRM, &n_sig, &o_sig); // 設定SIGALRM的處理行為

/*對SIGALRM信號設置阻塞,防止在掛起前出現遞達態*/

sigemptyset(&nsigmask);

sigaddset(&nsigmask, SIGALRM);

sigprocmask(SIG_BLOCK, &nsigmask, &osigmask); // 設置新mask,備份舊mask

alarm(n_seconds); // 設置n秒的鬧鐘

/*對原有的mask取消SIGALRM的阻塞*/

tmpsigmask = osigmask;

sigdelset(&tmpsigmask, SIGALRM);

sigsuspend(&tmpsigmask); // 掛起等待沒有被阻塞的信號

sigprocmask(SIG_SETMASK, &osigmask, NULL); // 還原mask

sigaction(SIGALRM, &o_sig, NULL); // 還原處理行為

unsigned int unsletp = alarm(0); // 獲取剩余的睡眠時間

/*因為如果沒有睡眠夠n_seconds就收到了一個喚醒信號,那么再次調用alarm會返回剩余的時間*/

return unsletp;

}

int main(void)

{

int ans = mysleep(5);

printf("%d\n", ans);

return 0;

}

本文同步分享在 博客“Ch_zaqdt”(CSDN)。

如有侵權,請聯系 support@oschina.cn 刪除。

本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

總結

以上是生活随笔為你收集整理的linux多线程时序问题,Linux时序竞态问题(sleep函数的实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。