注意指標修飾符的準確含義

2021-09-06 20:28:44 字數 1671 閱讀 7255

首先從一起多執行緒無鎖演算法的事故說起,以下是乙個無鎖棧的實現測試,但在開-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言語中很用常,但是近最讀 的時候常常搞不清楚,索搜...