1、LINUX下多線程編譯問題
你編譯的時候有加多線程連接選項嗎? 要加上 -lpthread 或者 -pthread (盡量選後者)
例如 gcc -pthread -o test main.cpp
另外你的線程創建的不對,函數指針不能強轉類型(這里也不用轉)
pthread_create(&procter_t,NULL,(void*)procter_f,NULL);
pthread_create(&consumer_t,NULL,(void*)consumer_f,NULL);
應該是
pthread_create(&procter_t,NULL,procter_f,NULL);
pthread_create(&consumer_t,NULL,consumer_f,NULL);
2、多線程編程的原則以及Sem信號量和Mutex互斥鎖的區別
以下兩種類型:
二值信號量:最簡單的信號量形式,信號量的值只能取0或1,類似於互斥鎖。
註:二值信號量能夠實現互斥鎖的功能,但兩者的關注內容不同。信號量強調共享資源,只要共享資源可用,其他進程同樣可以修改信號量的值;互斥鎖更強調進程,佔用資源的進程使用完資源後,必須由進
3、多線程同步時,互斥鎖和信號量是否應該定義為全局變數? sem_t pthread_mutex_t
全局變數總是不好的
將他們定義在類中比較合適,這樣在構造函數與析構函數中分別創建和銷毀
4、JAVA 模擬PV 多線程並發
不知道你在說什麼, 不過貌似是值傳遞的問題, 把一個int型的成員變數當方法參數傳遞到方法內, 然後想通過在方法內的遞減操作影響到原來的int型那個成員變數? 把問題描述清楚很重要~
5、急求!!多線程生產者消費者問題的c語言程序,要源碼、已在linux中執行過的文件,最好有截圖!!
||#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
#include<string.h>
#define BUFSIZE 4096
#define SEM_IN_TASK "INX_TASK"
#define SEM_OUT_TASK "OUTX_TASK"
sem_t *sem_in;
sem_t *sem_out;
main(int argc, char** argv) // map a normal file as shared mem:
{
int fd,i;
char *p_map;
char temp;
fd=open(argv[1],O_CREAT|O_RDWR|O_TRUNC,00777);
//lseek(fd,sizeof(people)*5-1,SEEK_SET);
write(fd,"",1);
p_map = (char*) mmap( NULL,BUFSIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0 );//建立共享內存
close( fd );
sem_unlink(SEM_IN_TASK);
sem_unlink(SEM_OUT_TASK);
sem_in = sem_open(SEM_IN_TASK,O_CREAT|O_EXCL,0644,1); //1ok
sem_out=sem_open(SEM_OUT_TASK,O_CREAT|O_EXCL,0644,0); //0ok
printf("[sem_in] [%d]\n",sem_in);
printf("[sem_out] [%d]\n",sem_out);
if(sem_in == SEM_FAILED||sem_out == SEM_FAILED)
{
perror("wangsha-unable to create semaphore");
sem_unlink(SEM_IN_TASK);
sem_unlink(SEM_OUT_TASK);
exit(-1);
}
memset(p_map,0,BUFSIZE);
while(1)
{
//printf("---------A waitting B-----------\n\n\n\n");
sem_wait(sem_out);
printf("A:%s\n",p_map );
memset(p_map,'a',100);
sem_post(sem_in);
//printf("------------A emit B-----------\n\n\n\n");
}
munmap( p_map, BUFSIZE );
printf( "umap ok \n" );
}
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
#include<string.h>
#define SEM_IN_TASK "INX_TASK"
#define SEM_OUT_TASK "OUTX_TASK"
#define BUFSIZE 4096
sem_t *sem_in;
sem_t *sem_out;
main(int argc, char** argv) // map a normal file as shared mem:
{
int fd =-1;
int i= 0;
char *p_map;
double consumetime = 0.0;
struct timeval process_stat , process_end;
fd=open( argv[1],O_CREAT|O_RDWR,00777 );
p_map = (char*)mmap(NULL,BUFSIZE,PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
sem_in = sem_open(SEM_IN_TASK,O_CREAT,0644,0); //0ok
sem_out=sem_open(SEM_OUT_TASK,O_CREAT,0644,1); //1ok
printf("[sem_in] [%d]\n",sem_in);
printf("[sem_out] [%d]\n",sem_out);
if(sem_in == SEM_FAILED||sem_out == SEM_FAILED)
{
perror("unable to create semaphore-wang");
sem_unlink(SEM_OUT_TASK);
sem_unlink(SEM_IN_TASK);
exit(-1);
}
memset(p_map,0,BUFSIZE);
//gettimeofday(&process_stat,NULL);
//while(1)
for(i =0;i<50000;i++)
{
memset(p_map,'b',100);
//printf("------------B emit A-----------\n\n\n\n");
sem_post(sem_out);
usleep(200);
sem_wait(sem_in);
//printf("------------A emit B-----------\n\n\n\n");
printf( "B:%s\n",p_map );
}
//gettimeofday(&process_end,NULL);
//consumetime = (double)(process_end.tv_sec - process_stat.tv_sec)*1e6 +(double)(process_end.tv_usec - process_stat.tv_usec)/1e6;
//printf("consumetime:[%f]\n",consumetime);
munmap( p_map,BUFSIZE );
}
如果對你有幫助,請給分哦,謝謝!
6、linux下多線程同步
你的問題不是互斥的問題,而是傳給子線程的 i 是指針,在子線程獲取 *arg 時,主線程的 for 循環可能已經修改或者沒有修改 i 的值,從而出現問題。下面的代碼直接把 i 的值傳給子線程,而不是傳指針,就不會有問題了。
7、C語言多線程輸出不正常求高手指點
線程參數,傳地址使用動態分配吧,你只用一個buffer,後面的很可能就把前面的給覆蓋了。
把所有的輸出printf使用一個互斥的信號量同步一下就行了吧,C的標准庫不是線程安全的。
8、在Quartez中操作任務類設置阻塞時間,讓下個線程延遲,用sleep(5000)。但是下一個線程還是按時觸發了
援引CU上一篇帖子的內容:
「信號量用在多線程多任務同步的,一個線程完成了某一個動作就通過信號量告訴別的線程,別的線程再進行某些動作(大家都在semtake的時候,就阻塞在 哪裡)。而互斥鎖是用在多線程多任務互斥的,一個線程佔用了某一個資源,那麼別的線程就無法訪問,直到這個線程unlock,其他的線程才開始可以利用這 個資源。比如對全局變數的訪問,有時要加鎖,操作完了,在解鎖。有的時候鎖和信號量會同時使用的」
也就是說,信號量不一定是鎖定某一個資源,而是流程上的概念,比如:有A,B兩個線程,B線程要等A線程完成某一任務以後再進行自己下面的步驟,這個任務 並不一定是鎖定某一資源,還可以是進行一些計算或者數據處理之類。而線程互斥量則是「鎖住某一資源」的概念,在鎖定期間內,其他線程無法對被保護的數據進 行操作。在有些情況下兩者可以互換。
兩者之間的區別:
作用域
信號量: 進程間或線程間(linux僅線程間)
互斥鎖: 線程間
上鎖時
信號量: 只要信號量的value大於0,其他線程就可以sem_wait成功,成功後信號量的value減一。若value值不大於0,則sem_wait阻塞,直到sem_post釋放後value值加一
互斥鎖: 只要被鎖住,其他任何線程都不可以訪問被保護的資源
成功後否則就阻塞
以下是信號燈(量)的一些概念:
信號燈與互斥鎖和條件變數的主要不同在於」燈」的概念,燈亮則意味著資源可用,燈滅則意味著不可用。如果說後兩中同步方式側重於」等待」操作,即資 源不可用的話,信號燈機制則側重於點燈,即告知資源可用;沒有等待線程的解鎖或激發條件都是沒有意義的,而沒有等待燈亮的線程的點燈操作則有效,且能保持 燈亮狀態。當然,這樣的操作原語也意味著更多的開銷。
信號燈的應用除了燈亮/燈滅這種二元燈以外,也可以採用大於1的燈數,以表示資源數大於1,這時可以稱之為多元燈。
1. 創建和 注銷
POSIX信號燈標準定義了有名信號燈和無名信號燈兩種,但LinuxThreads的實現僅有無名燈,同時有名燈除了總是可用於多進程之間以外,在使用上與無名燈並沒有很大的區別,因此下面僅就無名燈進行討論。
int sem_init(sem_t *sem, int pshared, unsigned int value)
這是創建信號燈的API,其中value為信號燈的初值,pshared表示是否為多進程共享而不僅僅是用於一個進程。LinuxThreads沒有實現 多進程共享信號燈,因此所有非0值的pshared輸入都將使sem_init()返回-1,且置errno為ENOSYS。初始化好的信號燈由sem變 量表徵,用於以下點燈、滅燈操作。
int sem_destroy(sem_t * sem)
被注銷的信號燈sem要求已沒有線程在等待該信號燈,否則返回-1,且置errno為EBUSY。除此之外,LinuxThreads的信號燈 注銷函數不做其他動作。
2. 點燈和滅燈
int sem_post(sem_t * sem)
點燈操作將信號燈值原子地加1,表示增加一個可訪問的資源。
int sem_wait(sem_t * sem)
int sem_trywait(sem_t * sem)
sem_wait()為等待燈亮操作,等待燈亮(信號燈值大於0),然後將信號燈原子地減1,並返回。sem_trywait()為sem_wait()的非阻塞版,如果信號燈計數大於0,則原子地減1並返回0,否則立即返回-1,errno置為EAGAIN。
3. 獲取燈值
int sem_getvalue(sem_t * sem, int * sval)
讀取sem中的燈計數,存於*sval中,並返回0。
4. 其他
sem_wait()被實現為取消點,而且在支持原子」比較且交換」指令的體系結構上,sem_post()是唯一能用於非同步信號處理函數的POSIX非同步信號 安全的API。
----------------------------
線程同步:何時互斥鎖不夠,還需要條件變數?
假設有共享的資源sum,與之相關聯的mutex 是lock_s.假設每個線程對sum的操作很簡單的,與sum的狀態無關,比如只是sum++.那麼只用mutex足夠了.程序員只要確保每個線程操作 前,取得lock,然後sum++,再unlock即可.每個線程的代碼將像這樣
add()
{
pthread_mutex_lock(lock_s);
sum++;
pthread_mutex_unlock(lock_s);
}
如果操作比較復雜,假設線程t0,t1,t2的操作是sum++,而線程t3則是在sum到達100的時候,列印出一條信息,並對sum清零. 這種情況下,如果只用mutex, 則t3需要一個循環,每個循環里先取得lock_s,然後檢查sum的狀態,如果sum>=100,則列印並清零,然後unlock.如果sum& lt;100,則unlock,並sleep()本線程合適的一段時間.
這個時候,t0,t1,t2的代碼不變,t3的代碼如下
print()
{
while (1)
{
pthread_mutex_lock(lock_s);
if(sum<100)
{
printf(「sum reach 100!」);
pthread_mutex_unlock(lock_s);
}
else
{
pthread_mutex_unlock(lock_s);
my_thread_sleep(100);
return OK;
}
}
}
這種辦法有兩個問題
1) sum在大多數情況下不會到達100,那麼對t3的代碼來說,大多數情況下,走的是else分支,只是lock和unlock,然後sleep().這浪費了CPU處理時間.
2) 為了節省CPU處理時間,t3會在探測到sum沒到達100的時候sleep()一段時間.這樣卻又帶來另外一個問題,亦即t3響應速度下降.可能在sum到達200的時候,t4才會醒過來.
3) 這樣,程序員在設置sleep()時間的時候陷入兩難境地,設置得太短了節省不了資源,太長了又降低響應速度.真是難辦啊!
這個時候,condition variable內褲外穿,從天而降,拯救了焦頭爛額的你.
你首先定義一個condition variable.
pthread_cond_t cond_sum_ready=PTHREAD_COND_INITIALIZER;
t0,t1,t2的代碼只要後面加兩行,像這樣
add()
{
pthread_mutex_lock(lock_s);
sum++;
pthread_mutex_unlock(lock_s);
if(sum>=100)
pthread_cond_signal(&cond_sum_ready);
}
而t3的代碼則是
print
{
pthread_mutex_lock(lock_s);
while(sum<100)
pthread_cond_wait(&cond_sum_ready, &lock_s);
printf(「sum is over 100!」);
sum=0;
pthread_mutex_unlock(lock_s);
return OK;
}
注意兩點:
1) 在thread_cond_wait()之前,必須先lock相關聯的mutex, 因為假如目標條件未滿足,pthread_cond_wait()實際上會unlock該mutex, 然後block,在目標條件滿足後再重新lock該mutex, 然後返回.
2) 為什麼是while(sum<100),而不是if(sum<100) ?這是因為在pthread_cond_signal()和pthread_cond_wait()返回之間,有時間差,假設在這個時間差內,還有另外一 個線程t4又把sum減少到100以下了,那麼t3在pthread_cond_wait()返回之後,顯然應該再檢查一遍sum的大小.這就是用 while的用意
9、關於linux下的多線程使用sem信號量的運行問題
不是信號量的問題
printf函數,是先寫到輸出緩沖,遇到\n時,或者緩沖區滿時,或者有強制輸出(fflush)時,才會將緩沖區里的內容輸出到屏幕上(標准輸出設備:stdout)。你的代碼裡面並沒有以上3個觸發條件的任意一種,所以printf的內存沒有實際輸出到屏幕上。
你只要在每個printf函數後面加上fflush(stdout);就可以了。