私はいくつかのマルチスレッドアプリケーションを持っています。これはメイン関数の一部です:
/* ...some code before... */
for(i=0; i<THREADS_COUNT; i++){
status = pthread_create(&threads[i], NULL, thread_main, NULL);
if(status < 0){
fprintf(stderr, "threads error\n");
exit(2);
}
}
status = sem_init(&sem, 0, 0);
if(status < 0){
fprintf(stderr, "sem_init error\n");
exit(4);
}
/* recv loop */
while (1) {
rv = recv(fd, buf, BUFSIZE, 0);
if(rv >= 0){
current = malloc(sizeof(struct queue_msg_list));
/* adding to our local queue */
if(current != NULL){
current->rv = rv;
current->h = h;
memcpy(&(current->buf), &buf, BUFSIZE);
current->next = NULL;
if(main_head == NULL){
main_head = main_tail = current;
}
else {
main_tail->next = current;
main_tail = current;
}
count++;
}
/* if we can carry the local queue to the queue for threads then we are doing it */
if(!pthread_mutex_trylock(&mlock)){
if(thread_head == NULL){
/* if the threads-queue is empty then replace queues */
thread_head = main_head;
thread_tail = main_tail;
} else {
/* if the threads-queue is not empty then add the local queue to the threads-queue */
thread_tail->next = main_head;
thread_tail = main_tail;
}
/* we increasing a semaphore of number of added elements */
for(i=0; i<count; i++){
sem_post(&sem);
printf("sem_post \n");
}
count = 0;
pthread_mutex_unlock(&mlock);
main_head = NULL;
main_tail = NULL;
}
}
}
/* ...some code after... */
そして、これはスレッドの関数です:
void *thread_main(void *arg)
{
struct queue_msg_list *current;
char buf[BUFSIZE] __attribute__ ((aligned));
struct nfq_handle *h;
int rv;
while(1){
sem_wait(&sem);
pthread_mutex_lock(&mlock);
/* if no blocking then we are working with packet and removing it from list after */
current = thread_head;
rv = current->rv;
h = current->h;
memcpy(&buf, &(current->buf), BUFSIZE);
thread_head = thread_head->next;
pthread_mutex_unlock(&mlock);
nfq_handle_packet(h, buf, rv);
free(current);
}
}
このアプリケーションは常に PC 上で正しく動作します。このアプリケーションをいくつかのルーターに配置しました (ファームウェアの Linux カーネルのバージョンは 2.6.30 です)。正しく動作することもありますが、正しく動作しないこともあります。:)
呼び出し時にスレッドがハングするsem_wait(&sem);
ことがありますが、セマフォの値が 0 を超えています (1、2、3 など)。なんで?
PSの戻り値を確認しようとしましsem_wait(&sem);
たが、取得できませんでした。