首先從一起多執行緒無鎖演算法的事故說起,以下是乙個無鎖棧的實現測試,但在開-o2以上優化的情況下它卻無法正常工作:
#include "lf_stack.h"
#include "kn_list.h"
#include "kn_time.h"
#include "kn_thread.h"
#include "kn_atomic.h"
typedef struct lockfree_stack
lockfree_stack,*lockfree_stack_t;
static void lfstack_push(lockfree_stack_t ls,kn_list_node *n)
}static kn_list_node* lfstack_pop(lockfree_stack_t ls)
}}volatile int count = 0;
atomic_32_t c1 = 0;
atomic_32_t c2 = 0;
struct element;
struct element *element_pool1;
struct element *element_pool2;
lockfree_stack lf_stack;
void *producer1(void *arg)
while(c1 > 0)
}printf("producer1 end\n");
return null;
}void *producer2(void *arg)
while(c2 > 0)
}return null;
}void *consumer(void *arg)
if(++count == 5000000)
if(ele->value == 1)
atomic_decrease(&c1);
else if(ele->value == 2)
atomic_decrease(&c2);
else
printf("%d\n",ele->value); }}
return null;
}int main()
表現就是consumer執行一定次數的pop之後死活也無法再彈出元素.不知道各位看官看出問題在哪沒有.
當問題再次出現以後,我用偵錯程式上去中斷,consumer執行緒,斷點正好在這行if(!lhead) return null;
,lhead為null,我回到上一層棧檢視實際上lockfree_stack.head
欄位並不是空,當我想檢視lhead的位址時,顯示無法檢視暫存器位址.
那麼問題就明確了,編譯器把lhead存放在了暫存器,導致無法發現head實際已經被改變.那麼問題來了,我明明將head標記為volatile的呀.
可是再仔細看看,volatile kn_list_node *head;
修飾符在指標之前,意思是指向的是volatile變數,而我實際要的是,乙個指標它本身是volatile的.ok,做相應的調整後kn_list_node * volatile head;
,問題解決.
總之,對指標修飾符關鍵的一點就是,在*
之前,修飾的是指向的目標.而在*
之後才是修飾指標本身.
const修飾符和指標
char const cpp1 null cpp1 char cp1 cp1 char c1 cpp1是乙個常量指標,所以cpp1需要在定義的時候初始化,它指向乙個char 型的指標cp1。char const cpp2 cpp2 char const cp2 const cp2 char c2 c...
C const修飾符和指標
c const修飾符和指標 開發工具與關鍵技術 c visualstudioconst修飾符,是用來修飾變數,被const修飾符,修飾過的變數,就叫做常量,常量是一種只能被讀取,不能被修改的量。在c 宣告乙個常量時,不但要const修飾符還有在宣告時就要給它進行初始化,你不給它初始化,編譯器就會報錯...
指標修飾C語言const修飾符探秘指標修飾
ps 今天上午,非常鬱悶,有很多簡單基礎的問題搞得我有些迷茫,哎,幾天不寫就忘。目前又不當coo,還是得用心記 哦!c言語是我接觸的第一門序程設計言語,時當還很傻很無邪,後來敏捷被各種高階言語 但是不得不說,c的位置真的無可撼動。const修飾符在c言語中很用常,但是近最讀 的時候常常搞不清楚,索搜...