Linux-執行緒
pthread
pthread_create建立一個執行緒並馬上開始執行執行緒函式;pthread_cancel取消執行緒,可線上程函式中設定“可取消性”的狀態和型別;pthread_join以阻塞方式等待指定執行緒結束,執行緒可用pthread_cancel取消,也可線上程函式中用pthread_exit((void *)val)和return (void *)val結束執行緒,執行緒正常結束時pthread_join(tid, retval)函式retval能收到執行緒結束返回值val,用pthread_cancel取消的返回值是PTHREAD_CANCELED=-1。
#include <stdio.h> #include <pthread.h> void *rountine(void *arg) { char *str = (char *)arg; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); int i; for(i = 0; i < 5; i++) { printf("NO.%d: %s \n", i, str); sleep(1); } //pthread_exit((void *)123); return (void *)123; } int main() { pthread_t tid; int ret = pthread_create(&tid, NULL, rountine, "hello world"); if(ret < 0) { printf("pthread_create: %d\n", strerror(ret)); return -1; } sleep(3); pthread_cancel(tid); int i; for(i = 0 ; i < 3; i++) { printf("Main: NO.%d----\n", i); sleep(1); } void *val; void **retval=&val; ret = pthread_join(tid, retval); if(ret < 0) { printf("pthread_join: %d\n", strerror(ret)); return -1; } printf("val=%d\n", (int)val); return 0; }
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);用來設定當前執行緒的“可取消性”狀態,並且將先前的狀態返回到oldstate引用中;“可取消性”狀態的合法值分別是:PTHREAD_CANCEL_ENABLE 和 PTHREAD_CANCEL_DISABLE。
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);用來設定當前執行緒的“可取消型別”,並且將先前的型別返回到oldtype引用中;“可取消型別”的合法值分別是:PTHREAD_CANCEL_DEFERRED :執行緒接收到取消操作後,直到執行到“可取消點”後取消;PTHREAD_CANCEL_ASYNCHRONOUS :執行緒接收到取消操作後,立即取消;pthread_testcancel
sem
sem訊號量同步
Compile and link with -std=gnu99 -pthread
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#define MAX 9
char array[MAX];
sem_t sem;
void fun1(int val)
{
sem_wait(&sem); //P
for(int i = 0; i < MAX; i++)
{
array[i] = val+i;
sleep(1);
printf("fun1: NO.%d: %d \n", i, array[i]);
}
sem_post(&sem); //v
}
void fun2(int val)
{
sem_wait(&sem); //P
for(int i = 0; i < MAX; i++)
{
array[i] = val+i;
sleep(1);
printf("fun2: NO.%d: %d \n", i, array[i]);
}
sem_post(&sem); //v
}
void *roun1(void *arg)
{
fun1(1);
return (void *)1;
}
void *roun2(void *arg)
{
fun2(10);
return (void *)2;
}
int main()
{
int ret = sem_init(&sem, 0, 1);
if(0 > ret)
{
perror("sem_init");
return -1;
}
pthread_t tid[2];
ret = pthread_create(&tid[0], NULL, roun1, NULL);
if(ret < 0)
{
printf("pthread_create: %s\n", strerror(ret));
return -1;
}
sleep(3);
ret = pthread_create(&tid[1], NULL, roun2, NULL);
if(ret < 0)
{
printf("pthread_create: %s\n", strerror(ret));
return -1;
}
ret = pthread_join(tid[0], NULL);
if(ret < 0)
{
printf("pthread_join: %s\n", strerror(ret));
return -1;
}
ret = pthread_join(tid[1], NULL);
if(ret < 0)
{
printf("pthread_join: %s\n", strerror(ret));
return -1;
}
}
mutex
mutex互斥鎖互斥
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX 9
char array[MAX];
pthread_mutex_t mutex;
void fun(int val)
{
pthread_mutex_lock(&mutex);
for(int i = 0; i < MAX; i++)
{
array[i] = val+i;
sleep(1);
printf("1: NO.%d: %d \n", i, array[i]);
}
pthread_mutex_unlock(&mutex);
}
void *roun1(void *arg)
{
fun(1);
return (void *)1;
}
void *roun2(void *arg)
{
fun(10);
return (void *)2;
}
int main()
{
int ret = pthread_mutex_init(&mutex, NULL);
if(0 > ret)
{
perror("pthread_mutex_init");
return -1;
}
pthread_t tid[2];
ret = pthread_create(&tid[0], NULL, roun1, NULL);
if(ret < 0)
{
printf("pthread_create: %s\n", strerror(ret));
return -1;
}
sleep(3);
ret = pthread_create(&tid[1], NULL, roun2, NULL);
if(ret < 0)
{
printf("pthread_create: %s\n", strerror(ret));
return -1;
}
ret = pthread_join(tid[0], NULL);
if(ret < 0)
{
printf("pthread_join: %s\n", strerror(ret));
return -1;
}
ret = pthread_join(tid[1], NULL);
if(ret < 0)
{
printf("pthread_join: %s\n", strerror(ret));
return -1;
}
}
條件變數
與互斥鎖不同,條件變數是用來等待而不是用來上鎖的;條件變數用來自動阻塞一個執行緒,直到某特殊情況發生為止;條件變數使我們可以睡眠等待某種條件出現;條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,
主要包括兩個動作:
一個執行緒等待"條件變數的條件成立"而掛起;另一個執行緒使"條件成立"(給出條件成立訊號);條件的檢測是在互斥鎖的保護下進行的;如果條件為假,一個執行緒自動阻塞,並釋放等待狀態改變的互斥鎖。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
//條件變數
pthread_cond_t cont = PTHREAD_COND_INITIALIZER;
//同步鎖
pthread_mutex_t mutex;
//執行標誌
int bIsrun = 1;
//工作執行緒
void *work(void *arg)
{
while(1)
{
if(0 > pthread_mutex_lock(&mutex))
{
exit(-1);
}
if(bIsrun)
{
if(0 != pthread_cond_wait (&cont, &mutex))
{
exit(-1);
}
}
if(0 > pthread_mutex_unlock(&mutex))
{
perror("work:pthread_mutex_unlock");
exit(-1);
}
static unsigned long counter=0;
printf("Running - %lu ... \r\n", counter++);
sleep(1);
}
return (void *)0;
}
int main(int argv, char **argc)
{
// 初始化
pthread_t thr;
pthread_attr_t threadAttr;
pthread_attr_init(&threadAttr);
pthread_mutex_init(&mutex, NULL);
pthread_create(&thr, &threadAttr, work, (void *)0);
//排程執行緒
while(1)
{
char ch = getchar();
switch(ch)
{
/*suspend*/
case 's':
case 'S':
pthread_mutex_lock(&mutex);
bIsrun = 1;
printf("bIsrun = 1\r\n");
pthread_mutex_unlock (&mutex);
break;
/*resume*/
case 'r':
case 'R':
pthread_mutex_lock(&mutex);
if(bIsrun)
{
bIsrun = 0;
pthread_cond_signal(&cont);
}
pthread_mutex_unlock (&mutex);
break;
/*exit*/
case 'q':
case 'Q':
exit(1);
default:
printf("Input something...\r\n");
break;
};
}
return 0;
}