天天看點

linux多線程實驗實驗報告,實驗七 Linux多線程互斥

實驗目的:

通過實驗掌握下列知識:

1、在Linux環境下,掌握pthread庫中的mutex對象,pthread_mutex_lock()函數,pthread_mutex_init和pthread_self()的用法。

2、在Linux環境下,掌握pthread_create()函數,pthread_join()函數的用法。

3、在Linux環境下,掌握pthread_cancel(pthread_t

thread),pthread_kill()的用法。

一、多線程和互斥鎖

(1) 使用頭檔案,pthread_mutex_lock()函數鎖住由mutex指定的mutex

對象。如果mutex已經被鎖住,調用pthread_mutex_lock()函數的線程阻塞直到mutex可用為止。pthread_self()可以獲得線程自身的ID。pthread_mutex_init用于互斥鎖的初始化。

#include

#include

#include

int data=0;

//共享資料

pthread_mutex_t mutex;

//互斥鎖

void *thread1(void

*argu)

//子線程執行函數

{

int

i;

if(pthread_mutex_lock(&mutex)!=0)

{

printf("lock error!\n");

return NULL;

}

for(i=0;i<6;i++)

{

printf("thread2: %d =

%d\n",pthread_self(),data++);

sleep(1);

}

if(pthread_mutex_unlock(&mutex)!=0)

{

printf("unlock error!\n");

return NULL;

}

}

int main()

{

pthread_t id;

int

i;

if(pthread_mutex_init(&mutex,NULL)!=0)

//在建立線程之前初始化鎖

{

printf("init error!\n");

return 1;

}

int

ret=pthread_create(&id,NULL,thread1,NULL);

//建立子線程

if(ret!=0)

{

printf("creata error!\n");

return 1;

}

if(pthread_mutex_lock(&mutex)!=0)

//對共享資料加鎖

{

printf("lock error!\n");

return 1;

}

for(i=0;i<6;i++)

{

printf("thread1: %d %d ",pthread_self(),data++);

sleep(1);

}

if(pthread_mutex_unlock(&mutex)!=0)

//對共享資料解鎖

{

printf("unlock error!\n");

return 1;

}

pthread_join(id,NULL);

return 0;

}

完成程式的編寫,輸入以下指令,對pthread1.c程式進行編譯,在編譯時,需要添加pthread的庫檔案。

$ gcc pthread1.c -o pthread1

–lpthread

二、多線程的建立

(2)線程的建立,利用線程調用函數。

#include

#include

#include

#include

#include

pthread_t

ntid;

void printids(const

char *s)

{

pid_t pid;

pthread_t

tid;

pid =

getpid();//傳回目前的程序号

tid =

pthread_self();

//傳回目前線程的線程ID号

printf("%s pid %u tid %u

(0x%x)\n", s, (unsigned int)pid, (unsigned int)tid, (unsigned

int)tid);

}

void *thr_fn(void

*arg)

{

printids(arg); return

NULL;

}

int

main(void)

{

int err;

err =

pthread_create(&ntid, NULL, thr_fn, "new thread:

"); //建立程序,并傳遞”new

thread”參數

if (err !=

0)

{

fprintf(stderr, "can't create

thread: %s\n", strerror(err));

exit(1);

}

printids("main

thread:");

//再次調用printids函數

sleep(1);

return 0;

}

完成程式的編寫,輸入以下指令,對thread2.c程式進行編譯,在編譯時,需要添加pthread的庫檔案。

$ gcc thread2.c -o thread2

-lpthread

./thread2

main thread: pid 7398 tid

3084450496 (0xb7d8fac0)

new thread: pid 7398 tid

3084446608 (0xb7d8eb90)

(3)定理三個函數線程,利用pthread_create ()中四個參數分别是:第一個參數為指向線程辨別符的指針;第二個參數用來設定線程屬性;第三個參數是線程運作函數的起始位址;

最後一個參數是運作函數的參數。pthread_join等待線程結束,第一個參數thread: 線程辨別符,即線程ID,辨別唯一線程;第二個參數用來設定使用者定義的指針,用來存儲被等待線程的傳回值。retval傳回值:0代表成功。失敗,傳回的則是錯誤号。

#include

#include

#include

#include

void *thr_fn1(void

*arg)

{

printf("thread 1

returning\n");

return (void

*)1;

}

void *thr_fn2(void

*arg)

{

printf("thread 2

exiting\n");

pthread_exit((void

*)2);

//調用pthread_exit函數終止執行

}

void *thr_fn3(void

*arg)

{

while(1) {

printf("thread 3

writing\n");

sleep(1);

}

}

int

main(void)

{

pthread_t

tid;

void *tret;

pthread_create(&tid, NULL,

thr_fn1, NULL);

//建立線程tid,調用thr_fn1函數

pthread_join(tid,

&tret);

//等待線程tid結束

printf("thread 1 exit code

%d\n", (int)tret);

//列印線程tid的傳回值

pthread_create(&tid, NULL,

thr_fn2, NULL);

//建立線程tid,調用thr_fn2函數

pthread_join(tid,

&tret);

//等待線程tid結束

printf("thread 2 exit code

%d\n", (int)tret);

//列印線程tid的傳回值

pthread_create(&tid, NULL,

thr_fn3, NULL);

//建立線程tid,調用thr_fn3函數

sleep(3);

//休眠3秒

pthread_cancel(tid);

//發送終止信号給thread線程

pthread_join(tid,

&tret);

//等待線程tid結束

printf("thread 3 exit code

%d\n", (int)tret);

return 0;

}

完成程式的編寫,輸入以下指令,對thread3.c程式進行編譯,在編譯時,需要添加pthread的庫檔案。

$ gcc thread3.c -o thread3

-lpthread

./thread3