行程與線程
撰寫中 ....
一個嵌入式系統可以沒有作業系統,只要所有的程式都連結在一起,然候用《輪詢》或《中斷》的方式進行輸出入協調就可以了!
但是當系統開始想要充分利用 CPU,讓某個程式在輸出入時,可以切換給另一個程式執行,這時就會需要《行程或線程》的支援了。
您可以參考 jserv 的 mini-arm-os 看看如何實作一個《支援線程的嵌入式作業系統》,以下是該專案的網址:
如果你想要學習的不是《自己設計嵌入式作業系統》,而是想學習 Linux 上的行程與線程用法的話,請看以下的範例:
Thread 範例
檔案: producer_consumer.c
/** PRODUCER - CONSUMER PROBLEM **/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <pthread.h>
#include <stdlib.h>
#define BUFSIZE 10
#define MUTEX 0
#define FULL 1
#define EMPTY 2
int semid;
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
};
int sem_create(int nsems) {
int id;
key_t key = 1234;
int semflg = IPC_CREAT | 0666;
id = semget(key, nsems, semflg);
if(id < 0)
{
perror("semget:");
exit (1);
}
return id;
}
void sem_initialise(int semno, int val) {
union semun un;
un.val = val;
if(semctl(semid, semno, SETVAL, un) < 0)
{
// printf("%d\n", semno);
perror("semctl:");
exit(2);
}
}
void *producer(void *id);
void *consumer(void *id);
void wait(int semno);
void signal(int semno);
int buffer[BUFSIZE], data;
int in = 0;
int out = 0;
int i = 10000;
int j = 10000;
int main (int argc, char *argv[]) {
semid = sem_create(3);
sem_initialise(MUTEX, 1);
sem_initialise(FULL, 0);
sem_initialise(EMPTY, 10);
pthread_t prod, cons;
pthread_create(&prod, NULL, producer, (void *)semid);
pthread_create(&cons, NULL, consumer, (void *)semid);
pthread_exit(NULL);
return 0;
}
void *producer(void *id) {
int semid = (int) id;
data = 0;
while(i--) {
wait(EMPTY);
wait(MUTEX);
/** Critical Section **/
buffer[in] = data;
in = (in + 1) % BUFSIZE;
data = (data + 1) % BUFSIZE;
printf("P:%d\n", data);
//printf("P\n");
signal(MUTEX);
signal(FULL);
}
pthread_exit(NULL);
}
void *consumer(void *id) {
int semid = (int) id;
while(j--)
{
wait(FULL);
wait(MUTEX);
/** Critical Section **/
data = buffer[out];
out = (out + 1) % BUFSIZE;
printf("C:%d\n", data);
/** **/
signal(MUTEX);
signal(EMPTY);
}
pthread_exit(NULL);
}
void wait(int semno) {
struct sembuf buf;
buf.sem_num = semno;
buf.sem_op = -1;
buf.sem_flg = 0;
if(semop(semid, &buf, 1) < 0) {
perror("semop:");
exit(2);
}
}
void signal(int semno) {
struct sembuf buf;
buf.sem_num = semno;
buf.sem_op = 1;
buf.sem_flg = 0;
if(semop(semid, &buf, 1) < 0)
{
perror("semop:");
exit(2);
}
}
執行:
$ gcc producer_consumer.c -lpthread -o producer_consumer
$ ./producer_consumer